在使用 LargeTitle 和带有 table 视图的分段控件时遇到问题

Having trouble with LargeTitle and a segmented control with a table view

可以在 https://github.com/SRowley90/LargeTitleIssueTestiOS

找到示例项目

我试图在 iOS 应用程序中将分段控件放置在大标题下方。我有一个包含分段控件的 UIToolbar。

向上滚动时 titletoolbar 的行为符合预期。

向下滚动导航栏时是正确的,但它不会将 UITabBar 或 UITableView 向下推,这意味着标题位于分段控件上方,如下图所示。

我很确定这与我设置的约束有关,但我不知道是什么。

我设置了位置 UITabBarDelegate 方法:

func position(for bar: UIBarPositioning) -> UIBarPosition {
    return .topAttached
}

tableView的委托带到某处: tableView.delegate = self

覆盖 scrollViewDidScroll 并更新 toolbar 位置外观(因为真实位置不应根据具有良好的弹跳效果而改变。


extension ViewController: UIScrollViewDelegate {
    override func scrollViewDidScroll(_ scrollView: UIScrollView) {
        var verticalOffset = scrollView.contentOffset.y + defaultNavigationBarHeight

        if scrollView.refreshControl?.isRefreshing ?? false {
            verticalOffset += 60 // After is refreshing changes its value the toolbar goes 60 points down
            print(toolbar.frame.origin.y)
        }

        if verticalOffset >= 0 {
            toolbar.transform = .identity
        } else {
            toolbar.transform = CGAffineTransform(translationX: 0, y: -verticalOffset)
        }
    }
}

您可以在应用转换之前使用以下检查,使默认 iOS 样式更加可靠和自然:

if #available(iOS 11.0, *) {
    guard let navigationController = navigationController else { return }
    guard navigationController.navigationBar.prefersLargeTitles else { return }
    guard navigationController.navigationItem.largeTitleDisplayMode != .never else { return }
}

对我来说,使用 UIScrollViewDelegate 与 CollectionView 和工具栏配合使用效果不佳。所以,我做了:

final class CollectionViewController: UICollectionViewController {
private var observesBag: [NSKeyValueObservation] = []
private let toolbar = UIToolbar()

    override func viewDidLoad() {
        super.viewDidLoad()
        let statusBarHeight = UIApplication.shared.statusBarFrame.height
        let navigationBarHeight = navigationController?.navigationBar.frame.height ?? 0
        let defaultNavigationBarHeight = statusBarHeight + navigationBarHeight

        let observation = navigationController!
            .navigationBar
            .observe(\.center, options: NSKeyValueObservingOptions.new) { [weak self] navBar, _ in
                guard let self = self else { return }
                let newNavigatonBarHeight = navBar.frame.height + statusBarHeight
                let yTranslantion = newNavigatonBarHeight - defaultNavigationBarHeight
                if yTranslantion > 0 {
                    self.toolbar.transform = CGAffineTransform(
                        translationX: 0,
                        y: yTranslantion
                    )
                } else {
                    self.toolbar.transform = .identity
                }

        }
        observesBag.append(observation)
    }
}

观察 navigationBar 的 "center" 是否有变化,然后翻译 y-axis 中的 toolbar

尽管当我尝试将此解决方案与 UIRefreshControl 和大标题一起使用时效果很好,但效果不佳。 我将刷新控件设置为:

   private func setupRefreshControl() {
        let refreshControl = UIRefreshControl()
        self.webView.scrollView.refreshControl = refreshControl
    }

UINavigationBar 的高度在完全刷新触发后改变。