推送到 detailviewController 时在 UINavigationBar 内动画子视图

animate subviews inside UINavigationBar when pushing to detailviewController

我的导航栏中有一些子视图。一个黑色方块,一些标题和一个蓝色条。当推送到细节 viewController 时,我希望我的子视图隐藏(动画)。 我使用以下方式将地铁添加到主视图控制器内的导航栏 self.navigationController?.navigationBar.addsubView(mySubview).

目前看起来像他的:

在细节中隐藏(动画)那些子视图的正确方法是什么 viewController?

你的问题很有意思。没想过导航栏。

UINavigationController用作根控制器时,所有UIViewControllers都存储在它的堆栈中,这意味着所有UIViewControllers共享一个navigationBar。 您在第一个 UIViewController 中将 mySubView 添加到 navigationBar。如果想在详情页隐藏,可以直接搜索subviews

第一步,需要给mySubView一个标签,可以是标签,也可以是自定义类型,方便后面判断。

在第一页

   import SnapKit 

   mySubView = UIView()
   mySubView?.tag = 999
   mySubView?.backgroundColor = .red
   mySubView?.translatesAutoresizingMaskIntoConstraints = false

   let navBar = navigationController?.navigationBar
   navBar!.addSubview(mySubView!)

   mySubView!.snp.makeConstraints { (make) in
       make.left.equalTo(navBar!).offset(100)
       make.centerY.equalTo(navBar!)
       make.width.height.equalTo(50)
   }

在详情页,我删除了isHidden,并用属性保存了navigationBar,因为navigationBar = nil在手势中。如果SnapKit不熟悉,多花几分钟学习。

   var mySubView: UIView? = nil
   var navBar: UINavigationBar?

   override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        // Do any additional setup after loading the view.

    navigationController?.interactivePopGestureRecognizer?.addTarget(self, action: #selector(backGesture))
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        homeNavigationBarStatus()
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        homeNavigationBarStatus()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        if mySubView == nil {
            for view: UIView in (navigationController?.navigationBar.subviews)! {
                if view.tag == 999 {
                    mySubView = view
                }
            }
        }

        UIView.animate(withDuration: 1, delay: 0, options: .curveEaseOut, animations: {
            self.detailNavigationBarStatus()
        }, completion: nil)
    }

    func detailNavigationBarStatus(){
        changingNavigationBarStatus(progress: 0)
    }

    func homeNavigationBarStatus(){
        changingNavigationBarStatus(progress: 1.0)
    }

    func changingNavigationBarStatus(progress:CGFloat){
        mySubView?.alpha = progress
        mySubView?.snp.updateConstraints({ (make) in
           make.left.equalTo(navBar!).offset(100 * progress)
        })
    }

    @objc func backGesture(sender: UIScreenEdgePanGestureRecognizer) {
        switch sender.state {
            case .changed:
                let x = sender.translation(in: view).x
                progress =  x / view.frame.width
                changingNavigationBarStatus(progress: progress)

            default:
                break
        }
    }

但是使用tag值不够优雅,可以为mySubView创建一个具体的class,也可以通过class判断。