常规高度导航栏的滚动边缘外观

Posted

技术标签:

【中文标题】常规高度导航栏的滚动边缘外观【英文标题】:Scrolling edge appearance for regular height navigation bar 【发布时间】:2021-07-08 08:34:54 【问题描述】:

我想知道是否有人知道如何让滚动边缘外观在正常高度的导航栏(不是大标题)上工作,就像在一些 Apple 自己的应用程序中一样。 在提醒应用程序中,您可以看到导航栏是清晰的,但随着表格/集合视图向上滚动,它会动画更改导航栏以具有半透明背景。我知道我可以在我的应用程序中使用大标题来实现这种行为,但我想用 2 个垂直堆叠的标签来模仿大标题,就像在 Stocks 应用程序中一样。

我试过以下代码:

// default appearance with clear nav bar and no shadow
let appearance = UINavigationBarAppearance()
appearance.configureWithTransparentBackground()
appearance.backgroundColor = UIColor.clear
appearance.titleTextAttributes = [.foregroundColor: UIColor.lightText]

// scrolled appearance with the default background
// used when there's content behind the navigation view
let appearance2 = UINavigationBarAppearance()
appearance2.configureWithDefaultBackground()
//        appearance2.backgroundColor = UIColor.systemBlue
appearance2.titleTextAttributes = [.foregroundColor: UIColor.lightText]

//use clear style when there's no content behind it
navigationItem.standardAppearance = appearance

//use default style when there's content behind it
navigationItem.scrollEdgeAppearance = appearance2

当我滚动时,您可以在提醒应用中看到我的意思 Video of Reminders app scrolling navigation bar appearance behaviour

这是我的应用程序中的内容,忽略导航栏中显示的标签,因为它在滚动时会发生变化 Video of Simulator scrolling

如果你们能帮助我,将不胜感激

【问题讨论】:

这是 ios 15 中的默认行为 - 默认情况下,所有导航栏在滚动到顶部时都是透明的。 感谢您的提醒,我最初是使用 iOS 14 构建的,但它可以与下面的答案一起使用。 【参考方案1】:

根据我的测试,该方法相当简单。请参考下面我的代码以及下面显示的结果的 gif


class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource 

    @IBOutlet weak var tv: UITableView!

    //Custom TitleView for your navigation bar
    var titleLabel: UILabel! // 1

    override func viewDidLoad() 
        super.viewDidLoad()
        tv.delegate = self
        tv.dataSource = self

        title = nil // 2
        navigationController?.navigationBar.prefersLargeTitles = true // 2

        // Creating and setting a UILabel as the new titleView
        titleLabel = UILabel()
        titleLabel.text = "Listen Now"
        navigationItem.titleView = titleLabel // 3

        // MOST CRUCIAL
        tv.contentInset.top = -20 // 4
    

    // MARK: UITableView delegates & datasource
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return 100
    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell")!
        cell.largeContentTitle = "Hello"
        return cell
    

    稍后您将需要UILabel,将其设置为navigationItem.titleView 设置您的title = nil 并确保标题为Large title 将您的自定义标题(即我的代码中的titleLabel)设置为titleView 最关键的部分是将tableView 的contentInset.top 设置为您认为合适的值。对我来说,最佳位置在-20 附近(减小此值以使单元格更靠近导航栏),但您可以为其设置不同的值。 contentInset.top 相当于在CSS 中添加top padding,它添加了从tableview 顶部到显示第一个单元格 的位置

【讨论】:

很抱歉回复得太晚了,因为这是个人项目,所以忙于工作。可以确认这对在 Apple 的 Fitness 应用程序中重新创建摘要屏幕的导航栏副标题动画的过程有很大帮​​助

以上是关于常规高度导航栏的滚动边缘外观的主要内容,如果未能解决你的问题,请参考以下文章

jQuery:在页面滚动时更改固定顶部导航栏的文本颜色

Swift - 滚动时缩小导航栏

在视图控制器中重置导航栏的外观

实现侧边导航栏的悬浮设置

如何获取Android手机底部导航栏的高度

如何正确设置 UIScrollView 高度