Your question is very interesting. I never thought about the navigation bar.
When UINavigationController
is used as the root controller, all UIViewControllers
are stored in its stack, meaning that all UIViewControllers
share a navigationBar
.
You added mySubView
to navigationBar
in the first UIViewController
. If you want to hide it on the details page, you can search for subviews directly.
The first step, you need to give mySubView
a tag, which can be a tag, or it can be a custom type, which is convenient for later judgment.
On the first page
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)
}
On the details page, I deleted isHidden
and saved navigationBar
with the attribute because navigationBar = nil
during the gesture. If SnapKit
is unfamiliar, take a few more minutes to learn.
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
}
}
However, using tag values is not elegant enough, you can create a specific class for mySubView
, which can also be judged by class.