development

iOS에서 애니메이션으로 탭 막대를 숨기는 방법은 무엇입니까?

big-blog 2020. 12. 13. 10:07
반응형

iOS에서 애니메이션으로 탭 막대를 숨기는 방법은 무엇입니까?


그래서 IBAction에 연결된 버튼이 있습니다. 버튼을 누르면 iOS 앱의 탭 바를 애니메이션으로 숨기고 싶습니다. 이것 [self setTabBarHidden:hidden animated:NO];또는 이것은 [self.tabBarController setTabBarHidden:hidden animated:YES];작동하지 않습니다. 이것은 애니메이션이없는 내 코드입니다.

- (IBAction)picture1:(id)sender {
    [self.tabBarController.tabBar setHidden:YES];
}

어떤 도움이라도 대단히 감사하겠습니다 : D


다음 공식을 사용하여보기 애니메이션을 계속 사용할 수 있도록 노력합니다.

// pass a param to describe the state change, an animated flag and a completion block matching UIView animations completion 
- (void)setTabBarVisible:(BOOL)visible animated:(BOOL)animated completion:(void (^)(BOOL))completion {

    // bail if the current state matches the desired state
    if ([self tabBarIsVisible] == visible) return (completion)? completion(YES) : nil;

    // get a frame calculation ready
    CGRect frame = self.tabBarController.tabBar.frame;
    CGFloat height = frame.size.height;
    CGFloat offsetY = (visible)? -height : height;

    // zero duration means no animation
    CGFloat duration = (animated)? 0.3 : 0.0;

    [UIView animateWithDuration:duration animations:^{
        self.tabBarController.tabBar.frame = CGRectOffset(frame, 0, offsetY);
    } completion:completion];
}

//Getter to know the current state
- (BOOL)tabBarIsVisible {
    return self.tabBarController.tabBar.frame.origin.y < CGRectGetMaxY(self.view.frame);
}

//An illustration of a call to toggle current state
- (IBAction)pressedButton:(id)sender {
    [self setTabBarVisible:![self tabBarIsVisible] animated:YES completion:^(BOOL finished) {
        NSLog(@"finished");
    }];
}

스토리 보드로 작업 할 때 푸시시 탭 바를 숨기도록 View Controller를 쉽게 설정할 수 있습니다. 대상 View Controller에서이 확인란을 선택하기 만하면됩니다.
여기에 이미지 설명 입력


확장을 사용하는 Swift 3.0 버전 :

extension UITabBarController {

    private struct AssociatedKeys {
        // Declare a global var to produce a unique address as the assoc object handle
        static var orgFrameView:     UInt8 = 0
        static var movedFrameView:   UInt8 = 1
    }

    var orgFrameView:CGRect? {
        get { return objc_getAssociatedObject(self, &AssociatedKeys.orgFrameView) as? CGRect }
        set { objc_setAssociatedObject(self, &AssociatedKeys.orgFrameView, newValue, .OBJC_ASSOCIATION_COPY) }
    }

    var movedFrameView:CGRect? {
        get { return objc_getAssociatedObject(self, &AssociatedKeys.movedFrameView) as? CGRect }
        set { objc_setAssociatedObject(self, &AssociatedKeys.movedFrameView, newValue, .OBJC_ASSOCIATION_COPY) }
    }

    override open func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        if let movedFrameView = movedFrameView {
            view.frame = movedFrameView
        }
    }

    func setTabBarVisible(visible:Bool, animated:Bool) {
        //since iOS11 we have to set the background colour to the bar color it seams the navbar seams to get smaller during animation; this visually hides the top empty space...
        view.backgroundColor =  self.tabBar.barTintColor 
        // bail if the current state matches the desired state
        if (tabBarIsVisible() == visible) { return }

        //we should show it
        if visible {
            tabBar.isHidden = false
            UIView.animate(withDuration: animated ? 0.3 : 0.0) {
                //restore form or frames
                self.view.frame = self.orgFrameView!
                //errase the stored locations so that...
                self.orgFrameView = nil
                self.movedFrameView = nil
                //...the layoutIfNeeded() does not move them again!
                self.view.layoutIfNeeded()
            }
        }
            //we should hide it
        else {
            //safe org positions
            orgFrameView   = view.frame
            // get a frame calculation ready
            let offsetY = self.tabBar.frame.size.height
            movedFrameView = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height + offsetY)
            //animate
            UIView.animate(withDuration: animated ? 0.3 : 0.0, animations: {
                self.view.frame = self.movedFrameView!
                self.view.layoutIfNeeded()
            }) {
                (_) in
                self.tabBar.isHidden = true
            }
        }
    }

    func tabBarIsVisible() ->Bool {
        return orgFrameView == nil
    }
}
  • 이것은 몇 시간 동안 놀아 본 Sherwin Zadeh의 입력을 기반으로합니다.
  • 탭바 자체를 이동하는 대신보기의 프레임을 이동합니다. 이렇게하면 탭 바가 화면 하단에서 멋지게 슬라이드되지만 ...
  • ... UITabbarcontroller 내부에 표시된 콘텐츠가 전체 화면을 차지한다는 장점이 있습니다!
  • 또한 AssociatedObject 기능을 사용하여 서브 클래 싱없이 UIView에 데이터를 첨부하므로 확장이 가능합니다 (확장은 저장된 속성을 허용하지 않음).

여기에 이미지 설명 입력


Apple 문서에 따라 UIViewController의 hidesBottomBarWhenPushed 속성, 부울 값으로, 뷰 컨트롤러가 탐색 컨트롤러에 푸시 될 때 화면 하단의 도구 모음이 숨겨져 있는지 여부를 나타냅니다.

최상위 뷰 컨트롤러의이 속성 값은 도구 모음이 표시되는지 여부를 결정합니다.

탭 표시 줄을 숨기는 권장 방법은 다음과 같습니다.

    ViewController *viewController = [[ViewController alloc] init];
    viewController.hidesBottomBarWhenPushed = YES;  // This property needs to be set before pushing viewController to the navigationController's stack. 
    [self.navigationController pushViewController:viewController animated:YES];

그러나이 접근 방식은 각 viewController에만 적용되며 탐색 컨트롤러의 스택에 푸시하기 전에 다른 viewController에서 동일한 hidesBottomBarWhenPushed 속성을 설정하기 시작하지 않는 한 다른보기 컨트롤러로 전파되지 않습니다.


Swift 버전 :

@IBAction func tap(sender: AnyObject) {
    setTabBarVisible(!tabBarIsVisible(), animated: true, completion: {_ in })
}


// pass a param to describe the state change, an animated flag and a completion block matching UIView animations completion
func setTabBarVisible(visible: Bool, animated: Bool, completion:(Bool)->Void) {

    // bail if the current state matches the desired state
    if (tabBarIsVisible() == visible) {
        return completion(true)
    }

    // get a frame calculation ready
    let height = tabBarController!.tabBar.frame.size.height
    let offsetY = (visible ? -height : height)

    // zero duration means no animation
    let duration = (animated ? 0.3 : 0.0)

    UIView.animateWithDuration(duration, animations: {
        let frame = self.tabBarController!.tabBar.frame
        self.tabBarController!.tabBar.frame = CGRectOffset(frame, 0, offsetY);
    }, completion:completion)
}

func tabBarIsVisible() -> Bool {
    return tabBarController!.tabBar.frame.origin.y < CGRectGetMaxY(view.frame)
}

Swift 4에서 Sherwin Zadeh의 답변을 다시 작성하십시오.

/* tab bar hide/show animation */
extension AlbumViewController {
    // pass a param to describe the state change, an animated flag and a completion block matching UIView animations completion
    func setTabBarVisible(visible: Bool, animated: Bool, completion: ((Bool)->Void)? = nil ) {

        // bail if the current state matches the desired state
        if (tabBarIsVisible() == visible) {
            if let completion = completion {
                return completion(true)
            }
            else {
                return
            }
        }

        // get a frame calculation ready
        let height = tabBarController!.tabBar.frame.size.height
        let offsetY = (visible ? -height : height)

        // zero duration means no animation
        let duration = (animated ? kFullScreenAnimationTime : 0.0)

        UIView.animate(withDuration: duration, animations: {
            let frame = self.tabBarController!.tabBar.frame
            self.tabBarController!.tabBar.frame = frame.offsetBy(dx: 0, dy: offsetY)
        }, completion:completion)
    }

    func tabBarIsVisible() -> Bool {
        return tabBarController!.tabBar.frame.origin.y < view.frame.maxY
    }
}

[Swift4.2]

다음에 대한 확장을 만들었습니다 UITabBarController.

import UIKit

extension UITabBarController {
    func setTabBarHidden(_ isHidden: Bool, animated: Bool, completion: (() -> Void)? = nil ) {
        if (tabBar.isHidden == isHidden) {
            completion?()
        }

        if !isHidden {
            tabBar.isHidden = false
        }

        let height = tabBar.frame.size.height
        let offsetY = view.frame.height - (isHidden ? 0 : height)
        let duration = (animated ? 0.25 : 0.0)

        let frame = CGRect(origin: CGPoint(x: tabBar.frame.minX, y: offsetY), size: tabBar.frame.size)
        UIView.animate(withDuration: duration, animations: {
            self.tabBar.frame = frame
        }) { _ in
            self.tabBar.isHidden = isHidden
            completion?()
        }
    }
}


애니메이션에서 tabBar의 프레임을 설정해보십시오. 튜토리얼을 참조하십시오 .

그렇게하는 것은 나쁜 습관 입니다. UIViewController속성 hidesBottomBarWhenPushed로 설정하여 푸시 할 때 tabBar 표시 / 숨기기 를 설정해야합니다 YES.


신속한 3.0 / iOS10 / Xcode 8에서 시도했습니다.

    self.tabBarController?.tabBar.isHidden = true

내 컨트롤러가 표시 될 때 설정했습니다. (및 탐색 후 뒤로 가면 숨기기)

override func viewWillAppear(_ animated: Bool) {

        super.viewWillAppear(animated)
        self.tabBarController?.tabBar.isHidden = false

    }

    override func viewWillDisappear(_ animated: Bool) {
                super.viewWillDisappear(animated)
        self.tabBarController?.tabBar.isHidden = true

    }

BTW : 다른 통풍구가 결국 숨기기 / 표시를 트리거 할 수 있으므로 표시 여부에 관계없이 저장할 플래그를 갖는 것이 좋습니다.


불행히도 나는 충분한 평판이 없기 때문에 HixField의 대답에 대해 언급 할 수 없으므로 이것을 별도의 대답으로 남겨 두어야합니다.

그의 대답에는에 대한 계산 된 속성이 없습니다 movedFrameView.

var movedFrameView:CGRect? {
  get { return objc_getAssociatedObject(self, &AssociatedKeys.movedFrameView) as? CGRect }
  set { objc_setAssociatedObject(self, &AssociatedKeys.movedFrameView, newValue, .OBJC_ASSOCIATION_COPY) }
}

나를 위해이 wrks는 : [self.tabBar setHidden:YES];
어디에서 자체 뷰 컨트롤러 인, 한 tabBar는 한 tabBar의 ID입니다.

참고 URL : https://stackoverflow.com/questions/20935228/how-to-hide-tab-bar-with-animation-in-ios

반응형