I have 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 wa
Setting prefersLargeTitles in code did work for me to make the NavBar title shrink and grow as you scroll. I did notice if you set the property through InterfaceBuilder, the shrinking feature didn't work.
Instead set in code like
self.navigationController?.navigationBar.prefersLargeTitles = true
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
}
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.
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
}
}
}