I got a View Controller embedded in a Navigation Controller with prefers large titles option set to true; inside the View Controller there’s a Scroll View.
I want to make the nav bar shrink when scrolling.
How could I archive this?
XCode 9, Swift 4, iOS 11
I have not achieved that it works using a UIScrollView but I archived that it works with other ViewControllers using a UITableView as first view.
If the tableView is not the first view, the large title fails to hide automatically. You most likely need to make sure your tableView is the first element in the main view’s subviews array.
I hope that this solves your problem.
Have you tried something like this? It converts the large title display mode when the content is scrolled up.
class P1ViewController: UIViewController, UIScrollViewDelegate
{
var canTransitionToLarge = false
var canTransitionToSmall = true
func scrollViewDidScroll(_ scrollView: UIScrollView)
{
if canTransitionToLarge && scrollView.contentOffset.y <= 0 {
UIView.animate(withDuration: 0.5) {
self.navigationItem.largeTitleDisplayMode = .always
}
canTransitionToLarge = false
canTransitionToSmall = true
}
else if canTransitionToSmall && scrollView.contentOffset.y > 0 {
UIView.animate(withDuration: 0.5) {
self.navigationItem.largeTitleDisplayMode = .never
}
canTransitionToLarge = true
canTransitionToSmall = false
}
}
}
This way is worked for me. i followed these steps: 1- Moving the TableView to top of the list (under safe area) in view controller scene. 2- Making FirstView and Loaded by FirstViewContoller.
I used dsk1306 solutions, see above. But in my case I had a WebView in the UIViewController with the large title.
So I had to set the UIWebView ScrollView delegate:
self.webView.scrollView.delegate = self
and
extension MyViewController: UIScrollViewDelegate {
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
if #available(iOS 11.0, *) {
UIView.animate(withDuration: 0.5, animations: {
self.navigationController?.navigationBar.prefersLargeTitles = (velocity.y < 0)
})
}
}
}
I had the similar problem, is was because of many UIScrollView-based view inside view controller and I was scrolling not first in hierarchy. Once it's only one it works fine with UIScrollView, WKWebView or UITextView without any line of code.
I've used something that is similar to Kamil Szostakowski's answer for view with UICollectionView.
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
UIView.animate(withDuration: 0.5, animations: {
self.navigationController?.navigationBar.prefersLargeTitles = (velocity.y < 0)
})
}
It may be not so smooth but I haven't found better option yet.
Try something like this:
extendedLayoutIncludesOpaqueBars = true
scrollView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(scrollView)
NSLayoutConstraint.activate([
scrollView.topAnchor.constraint(equalTo: view.topAnchor),
scrollView.leftAnchor.constraint(equalTo: view.leftAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
scrollView.rightAnchor.constraint(equalTo: view.rightAnchor)
])
I tested with storyboard approach, it is working. Make sure to set the scrollView & it's subviews Constraints.
Here with the test sample XCode project for references: https://github.com/DazChong/LargeTitleShrinkOnScrollView
If u have problem collapse root navigationBar from presented VC's scrollView, can try this: Add UIScrollView to RootVC. Important - UIScrollView must be root view(at index 0). In presentedVC we can use scrollViewDidScroll and set offset on our root UIScrollView. see here with gif and code RootVC view hierarchy: screenshot (sorry for link, not enough reputation)
in presentedVC try this
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if #available(iOS 11.0, *) {
let offset = scrollView.contentOffset
rootVC.scrollView.contentOffset = offset
}
}
You need to:
Pin scroll top view to super view top
Add
override func viewDidLoad() {
super.viewDidLoad()
scrollView?.alwaysBounceVertical = true
}
来源:https://stackoverflow.com/questions/46703469/shrink-large-title-when-scrolling-not-uitableviewcontroller-ios-11

