It was a great answer, but it took me some clarification to get everything right.
So the general idea is that you have text in the middle of your scrollView and when the user scrolls past that text, then you want it to become a new heading. Also, when you scroll back, you want it to go back to the default name again.


So, using the code that Gix sent, now converted to Swift 3, is how you do it.
Add these variables to the top of your viewController
var didChangeTitle = false let defaultTitle = "Default Title" let animateUp: CATransition = { let animation = CATransition() animation.duration = 0.5 animation.type = kCATransitionPush animation.subtype = kCATransitionFromTop animation.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionEaseInEaseOut) return animation }() let animateDown: CATransition = { let animation = CATransition() animation.duration = 0.5 animation.type = kCATransitionPush animation.subtype = kCATransitionFromBottom animation.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionEaseInEaseOut) return animation }()
In your viewDidLoad add this code to set the default title.
let titleLabelView = UILabel.init(frame: CGRect(x: 0, y: 0, width: 200, height: 44)) titleLabelView.backgroundColor = .clear titleLabelView.textAlignment = .center titleLabelView.textColor = UINavigationBar.appearance().tintColor titleLabelView.font = UIFont.boldSystemFont(ofSize: 16) titleLabelView.text = defaultTitle self.navigationItem.titleView = titleLabelView
Now you add the code to the scrollView delegate function:
extension MyViewController: UIScrollViewDelegate { func scrollViewDidScroll(_ scrollView: UIScrollView) { if scrollView.contentOffset.y >= (labelName.frame.origin.y + labelName.frame.height) && !didChangeTitle { if let label = navigationItem.titleView as? UILabel { label.layer.add(animateUp, forKey: "changeTitle") label.text = labelName.text } didChangeTitle = true } else if scrollView.contentOffset.y < labelName.frame.origin.y && didChangeTitle { if let label = navigationItem.titleView as? UILabel { label.layer.add(animateDown, forKey: "changeTitle") label.text = defaultTitle } didChangeTitle = false } } }
"labelName" var is the label in your scroll containing your future title.
source share