How to prevent Large Title from Collapsing

2020-06-13 08:30发布

The question is simple, how can I prevent a Large Title Navigation Bar from collapse when a scrollview scrolls down?

My navigation must have a large navigation bar at all times... so when a scrollview scroll, the navigation bar shouldn't collapse up, it should stay the same size, how can I do that?

This is how I set the largeTitle preferences

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.navigationItem.hidesBackButton = true
    presenter.expandForSimulatorLayoutIfNeeded()

}


func expandForSimulatorLayoutIfNeeded(){
            if !isExpanded{
        topMenu = TopMenu(frame: expandedNavigationFrame, interactor: interactor)
        oldNavigationBarFrame = navigationBar.frame
        self.navigationBar.addSubview(topMenu)
    }

    if #available(iOS 11.0, *) {
        self.navigationBar.prefersLargeTitles = true
    } else {
        self.navigationBar.frame = expandedNavigationFrame
    }

    let topConstraint = NSLayoutConstraint(item: topMenu, attribute: .top, relatedBy: .equal, toItem: navigationBar, attribute: .top, multiplier: 1, constant: 0)
    let leadingConstraint = NSLayoutConstraint(item: topMenu, attribute: .leading, relatedBy: .equal, toItem: navigationBar, attribute: .leading, multiplier: 1, constant: 0)
    let widthConstraint = NSLayoutConstraint(item: topMenu, attribute: .width, relatedBy: .equal, toItem: self.navigationBar, attribute: .width, multiplier: 1, constant: 0)
    let bottomConstraint = NSLayoutConstraint(item: topMenu, attribute: .bottom, relatedBy: .equal, toItem: navigationBar, attribute: .bottom, multiplier: 1, constant: 0)
    topMenu.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([leadingConstraint, widthConstraint, topConstraint, bottomConstraint])

}

3条回答
叛逆
2楼-- · 2020-06-13 09:02

To prevent the large tile nav bar from collapsing simply add a second view to your UIViewController in the viewDidLoad method.

view.addSubview(UIView())

For whatever reason, this breaks the link between your the UIScrollView and the nav bar.

查看更多
聊天终结者
3楼-- · 2020-06-13 09:15

A workaround i figured out is to add a placeholder view that is not CollectionView/TableView as the very first view in ViewController's base view. This first view will be attached to the top of the safeArea, height can be zero.

Using Storyboard/Xib:

See the below screenshot for this view with constraints

enter image description here

Next add another UIView to serve as a container view for your TableView/CollectionView. This container's top will be attached to bottom of the placeholder view. See the below screenshot for constraints of container view and TableView/CollectionView.

enter image description here

The key here is the first view in the view hierarchy as the navigation bar will check that to set the collapsing effect. Once it does not find it as a CollectionView/TableView, it will not collapse on scrolling.

Programmatically:

If you are setting up view's programmatically then you just need to add a placeholder view at the top.

e.g,

self.view.addSubview(UIView(frame: .zero))
self.view.addSubview(tableView) // or collectionView
查看更多
We Are One
4楼-- · 2020-06-13 09:16

If someone arrives here from SwiftUI land, this is a good way to keep your lists in large title mode.

// your content view ...

    var body: some View {
        VStack {
            PreventCollapseView()
            List {
                ForEach(things, id: \.self) { thing in
                    Text(thing.name)
                }
            }
        }
        .navigationBarTitle("All the things")
    }


// end of view


struct PreventCollapseView: View {

    private var mostlyClear = Color(UIColor(white: 0.0, alpha: 0.0005))

    var body: some View {
        Rectangle()
            .fill(mostlyClear)
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 1)
    }
}

查看更多
登录 后发表回答