Shrink large title when scrolling (not UITableViewController) iOS 11

走远了吗. 提交于 2019-12-17 19:13:33

问题


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


回答1:


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.




回答2:


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
        }
    }
}



回答3:


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



回答4:


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.

The screenshot of the solution




回答5:


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)
        })
    }
}

}



回答6:


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.




回答7:


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.




回答8:


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)
        ])



回答9:


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




回答10:


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
        }
}



回答11:


You need to:

  1. Pin scroll top view to super view top

  2. Add

override func viewDidLoad() {
    super.viewDidLoad()

    scrollView?.alwaysBounceVertical = true
  }


来源:https://stackoverflow.com/questions/46703469/shrink-large-title-when-scrolling-not-uitableviewcontroller-ios-11

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!