如何防止大标题折叠

14

问题很简单,当滚动视图向下滚动时,我如何防止大标题导航栏折叠?

我的导航栏必须始终有一个大的导航栏...所以当滚动视图滚动时,导航栏不应该折叠起来,它应该保持相同的大小,我该怎么做?

这是我设置大标题偏好的方式

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

}
4个回答

19

我找到的一个解决方法是在ViewController的基本视图中添加一个不是 CollectionView/TableView 的占位视图作为第一个视图。这个第一个视图将附加到安全区域的顶部,高度可以为零。

使用Storyboard/Xib:

请参见下面的屏幕截图以查看具有约束条件的此视图。

enter image description here

接下来,添加另一个UIView作为TableView/CollectionView的容器视图。该容器的顶部将附加到占位符视图的底部。请参见下面的屏幕截图以查看容器视图和 TableView/CollectionView 的约束条件。

enter image description here

关键在于视图层次结构中的第一个视图,因为导航栏会检查它以设置折叠效果。一旦它未将其识别为CollectionView/TableView,它就不会在滚动时折叠。

以编程方式:

如果您正在以编程方式设置视图,则只需在顶部添加一个占位符视图。

例如:

self.view.addSubview(UIView(frame: .zero))
self.view.addSubview(tableView) // or collectionView

7

如果有人从SwiftUI领域来到这里,这是一个保持列表处于大标题模式的好方法。

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


太好了,谢谢!我设置了 VStack(spacing; 0) 来使内容尽可能接近 PreventCollapseView - Jeremy
不幸的是,如果在列表中使用导航链接,这会导致行在返回导航后仍保持高亮。这是iOS 15之前已知的iOS错误。https://dev59.com/yVIG5IYBdhLWcg3wlCK8 - alionthego

3
为了防止大型瓷砖导航栏的折叠,只需在viewDidLoad方法中将第二个视图添加到您的UIViewController即可。
view.addSubview(UIView())

不知何故,这会导致你的UIScrollView与导航栏之间的链接断开。


1
如果您在故事板上创建了其他视图,则只需在viewDidLoad上调用以下方法即可。
private func preventLargeTitleCollapsing() {
    let dummyView = UIView()
    view.addSubview(dummyView)
    view.sendSubviewToBack(dummyView)
}

我的原始答案在这里

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接