11

我试图了解这是一个错误还是预期的行为。

iOS 10及更早版本上,我们可以设置自定义标题,使用navigationItem.titleView.
iOS 11上,设置 ournavigationItem.largeTitleDisplayMode = .always和设置时navigationItem.titleView = <Some cool UIButton>,它会同时显示普通导航标题栏和大导航标题。

插图: 在此处输入图像描述

总结一下:

我们如何在大导航标题上使用自定义 titleView?

编辑:这是预期的结果:

在此处输入图像描述

4

2 回答 2

6

我找不到任何关于此的文档,所以我玩了一下。似乎在 iOS 11 中,您将无法将该标题作为按钮并在左侧显示大。

我不知道这是一个错误还是预期的结果,因为它似乎是一个新功能。最新的 (iOS 11)人机界面指南(HIG) 讨论了较大的标题标签是一种为用户提供清晰上下文的方式。HIG 还讨论了按钮之间的空间。但是,没有讨论使用按钮作为标题。


为了重新创建,我设置了一个单一视图项目。我将视图控制器嵌入到导航控制器中。

ViewController.swift'sviewDidLoad中,我添加了以下代码:

    let titleButton = UIButton(type: .roundedRect)
    titleButton.setTitle("Hello Button!", for: UIControlState.normal)

    let navController = parent as! UINavigationController

    navController.navigationBar.topItem!.title = "Hello???"
    navController.navigationBar.topItem!.titleView = titleButton
    navController.navigationBar.prefersLargeTitles = true

这最终看起来像你的例子。

如果我

  • 设置.title为空字符串,或者注释掉行:导航栏被拉伸,并且没有标题文本显示(或在界面生成器中设置的标题文本显示)

  • 注释掉.prefersLargeTitles,或将其设置为false:导航栏是正常高度,按钮显示,但不显示标题文本。

  • 注释掉该titleView行,并且:

    • .prefersLargeTitles设置保留为truetitle文本在左侧显示较大,并且导航栏的高度被拉伸。
    • 设置.prefersLargeTitlesfalsetitle文本显示在顶部中心,导航栏是正常高度。

更新:链接到GitHub 上的示例项目

于 2017-10-23T16:58:16.637 回答
4

UINavigationBar通过使用子类并手动更改视图层次结构,我能够用自定义视图替换导航栏大标题:

@interface MYNavigationBar : UINavigationBar

@end
@implementation MYNavigationBar

// ...

- (void)layoutIfNeeded
{
    [self setupTitle];
    [super layoutIfNeeded];
}

- (void)setupTitle
{
    // UINavigationBar
    // -> ...
    // -> _UINavigationBarLargeTitleView
    //   -> UILabel << Big Title Label
    //   -> UIView
    //     -> UILabel << Big Title Label animating from back button during transitions

    for (UIView *view in self.subviews) {
        NSString *className = NSStringFromClass(view.classForCoder);
        if ([className containsString:@"LargeTitleView"]) {
            for (UIView *view2 in view.subviews) {
                if ([view2 isKindOfClass:[UILabel class]]) {
                    [self convertLabel:(UILabel *)view2];
                }
                for (UIView *view3 in view2.subviews) {
                    if ([view3 isKindOfClass:[UILabel class]]) {
                        [self convertLabel:(UILabel *)view3];
                    }
                }
            }
        }
    }
}

- (void)convertLabel:(UILabel*)label
{
    // I kept the original label in the hierarchy (with the background color as text color)
    // and added my custom view as a subview. 
    // This allow the transformations applied to the original label to be also applied to mine.
}

请注意,Apple可能会因为这个技巧而拒绝您的应用程序。

于 2019-08-07T12:23:37.310 回答