如何在 iOS 11 中引入的 UINavigationBar 的大标题视图上添加自定义视图

Posted

技术标签:

【中文标题】如何在 iOS 11 中引入的 UINavigationBar 的大标题视图上添加自定义视图【英文标题】:How can I add a custom view on the large title view of UINavigationBar introduced in iOS 11 【发布时间】:2017-10-07 12:22:12 【问题描述】:

我想在 UINavigationBar 的大标题视图上添加一个自定义子视图,就像 App Store 在 ios 11 中所做的那样。(右侧的“用户图标”)

我们可以通过UINavigationItem.titleView访问传统的导航栏区域,但是好像没有API可以访问大标题视图区域。

https://developer.apple.com/documentation/uikit/uinavigationitem/ https://developer.apple.com/documentation/uikit/uinavigationbar/

我使用 View Hierarchy Debugger 确认名称为“_UINavigationBarLargeTitleView”。 我可以在上面添加自定义视图吗?

【问题讨论】:

你也可以使用导航栏的标题视图,也可以改变导航栏的高度 你的意思是我需要创建一个 UINavigationBar 的子类? 无需子类化,使用自定义子视图设置 titleView 属性就足够了 我知道我们可以用titleView自定义传统的标题区域。我要自定义的不是titleView,而是iOS11 UI中的“Large Title Area”。很抱歉,由于声誉问题,我无法添加任何图片...google.co.jp/… 【参考方案1】:

解决方案依赖于大标题标签的子视图顺序而不是其私有类名,以使其符合 AppStore 准则。

class CustomLargeTitleNavigationBar: UINavigationBar 

    override func didMoveToSuperview() 
        super.didMoveToSuperview()

        if #available(iOS 11.0, *) 
            for subview in subviews 
                if let largeTitleLabel = subview.subviews.first(where:  $0 is UILabel ) as? UILabel 
                    let largeTitleView = subview
                    print("largeTitleView:", largeTitleView)
                    print("largeTitleLabel:", largeTitleLabel)
                    // you may customize the largeTitleView and largeTitleLabel here
                    break
                
            
        
    

【讨论】:

使用 didMoveToSuperview 时,这个解决方案似乎不起作用,你是如何在这个生命周期中解决这个问题的? @AmadeuCavalcanteFilho 当您说“不起作用”时,这可能与您的情况有关,不是吗?因为根据投票,它确实帮助了我自己 + 其他 5 个人。所以我建议创建一个最小的可重现案例,指定设备、iOS 版本和 Xcode 版本,准确描述什么不起作用(没有日志?错误大小?仅在旋转时?等)并将其发布到新堆栈中溢出问题。 抱歉,没早看到你的问题。我试图将 sn-p 与 SwiftUI 一起使用,我没有那段不起作用的代码,但我认为这是我的错误以及 SwiftUI 的不同生命周期与预期的行为相混淆。再次抱歉 好的,那么有必要专门针对 SwiftUI 提出一个新问题,据我所知,它的生命周期确实与 UIKit 不同。一个明显的区别是 SwiftUI 是 iOS 13+,而现在的问题是 iOS 11+。 这在 iOS 13 中不再起作用...您必须覆盖 layoutSubviews。【参考方案2】:

根据这篇文章,我猜应该或多或少是这样的。https://qiita.com/KikurageChan/items/4152c2d8ac89c601a054

import UIKit
@IBDesignable class CustomNavigationBar: UINavigationBar 
override func layoutSubviews() 
    super.layoutSubviews()
    if #available(iOS 11.0, *) 
        for subview in self.subviews 
            let stringFromClass = NSStringFromClass(subview.classForCoder)
            if stringFromClass.contains("UINavigationBarLargeTitleView") 
                //subview.frame.size.height = 30
                // Custom view
                subview.addSub.....

            
        
    
  

自定义导航栏

【讨论】:

这是否通过了 AppStore 审核? @RichardTopchiy 你是否通过了 appStore 的审核? 可以分享一下吗? 我很确定 OP 会希望使用公共 API 来实现这一点。这个解决方案很老套,很可能会从 Apple 获得回扣。就目前而言,没有用于在 UINavigationBarLargeTitleView 之上添加任何自定义视图的公共 API。我们只能修改其中的标签内容。

以上是关于如何在 iOS 11 中引入的 UINavigationBar 的大标题视图上添加自定义视图的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式关闭/禁用 iOS 11 中引入的屏幕截图弹出框?

ios 导航问题

UIBarButtonItem 在 ios6 中看起来很糟糕

如何识别 UITableView 前导和尾随滑动操作 (ios 11) 的当前活动位置?

我如何摆脱 Xcode 中的 IOS 版本“部分:在 IOS X 中引入”警告

iOS Navigation 使用的一些总结