xcode 11 beta 中的这种新导航栏行为是错误还是有意为之?

Is this new navigation bar behaviour in xcode 11 beta a bug or intended?

我在 Xcode 11 beta 中编译我的一个应用程序后注意到,当设置 prefersLargeTitles 时,导航栏没有背景。这是有意为之的行为吗?

我注意到消息应用现在是这样工作的,当向下滚动时可以看到一个大标题,没有导航栏背景。

这是用于设置 navBar 属性的代码:

 override func viewWillAppear(_ animated: Bool) {
    let textAttributes = [NSAttributedString.Key.foregroundColor:ThemeManager.shared.default1]
    self.navigationController?.navigationBar.largeTitleTextAttributes = textAttributes
    self.navigationController?.navigationBar.titleTextAttributes = textAttributes
    self.navigationController?.navigationBar.tintColor = ThemeManager.shared.default1
 self.navigationController?.setNavigationBarHidden(false, animated: true)
    self.navigationController?.navigationBar.prefersLargeTitles = true
    let nav = self.navigationItem
    nav.title = "My Profile"
}

这里有几张图片显示了不同之处:

左侧,编译于 Xcode 10,右侧,Xcode 11 beta:

在 11 Beta 版本上向上滚动后,背景会淡入。请注意,未在 Xcode 11 Beta 中编译的应用程序仍将以正常方式运行,仅在编译后发生一些变化原因。这是有意为之吗?我该如何恢复原来的行为?

这是 iOS 13.

的预期行为

Apple 的想法(在我看来很糟糕)是标题应该与内容合并以表明它是相关的。开始滚动后,当内容位于标题栏后面时,标题栏将呈现 "correct" 外观。

这很糟糕的原因是因为每个人目前都在计划他们的所有 UI 没有这种行为。所以新的行为应该是 opt-in 而不是强迫每个人 opt-out (即这个改变破坏了每个人的代码,如果你要破坏每个人的代码至少你应该清楚如何保持尝试过的以及过去 10 年的真实行为)。

就像你的情况一样,结果看起来很糟糕。在我的情况下,结果看起来也很糟糕。

Apple 没有给出答案,但表示您应该使用

- scrollEdgeAppearance

来自 UINavigationBar,以便在内容对齐时控制栏的外观 top-of-content 到 bottom-of-navbar ...在我的例子中,此方法 returns 无不过我目前不确定我们应该如何使用它。

这里好像也讨论了这个:

New UINavigationBar appearance in detail pane of UISplitViewController in iOS 13

因此当前的解决方法在您的视图控制器中似乎是这样的:

- (void)viewDidLoad;
{
    [super viewDidLoad];
    if (@available(iOS 13,*)){
        UINavigationBar *bar =self.navigationController.navigationBar;
        bar.scrollEdgeAppearance = bar.standardAppearance;
    }
}

它有效,但如果它是预期的方法,我不知道...

编辑:

这样做似乎确实会阻止对 UINavigationBar 的任何其他直接自定义,如前所述。可能从这里调整 scrollEdgeAppearance 是可行的方法。丑陋。丑陋。丑。

编辑:进展...现在正在管理后台。您需要调用它而不是直接设置 barTint。

@interface UINavigationBar (Compatibility)
- (void)setCompatibleTint:(UIColor *)fg andBarTint:(UIColor *)bg;
@end

@implementation UINavigationBar (Compatibility)
- (void)setCompatibleTint:(UIColor *)fg andBarTint:(UIColor *)bg;
{
    self.tintColor = fg;
    self.barTintColor = bg;
    if (@available(iOS 13,*)){
        // we need to tell it to adopt old style behavior first
        UINavigationBarAppearance *appearance = self.standardAppearance;
        appearance.backgroundColor = bg;
        NSDictionary *attributes = self.titleTextAttributes;
        appearance.titleTextAttributes = attributes;
        attributes = self.largeTitleTextAttributes;
        appearance.largeTitleTextAttributes = attributes;
        self.scrollEdgeAppearance = appearance;
        self.standardAppearance = appearance;
        self.compactAppearance = appearance;
    }
}
@end

我还不能完全确定文本属性,但它似乎是从背景色中流出的。这是一个完整的 PITA。

将其设置为子类并覆盖 barTint 会更好,但当然很多 UIKit objects 会自己创建这些条,因此您不会获得子类。

Swift 版本的 dbquarrel 解决方案。

首先声明你的textAttributes:

let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.red]

UINavigationBarAppearance() 中使用这些使您能够在 3 种不同的模式(scollEdge、标准和紧凑)中更改文本的颜色。

override func viewDidLoad() {
    super.viewDidLoad()
    if #available(iOS 13.0, *) {
        let appearance = UINavigationBarAppearance()
        appearance.largeTitleTextAttributes = textAttributes
        appearance.titleTextAttributes = textAttributes
        let bar = self.navigationController?.navigationBar
        bar?.scrollEdgeAppearance = appearance
        bar?.standardAppearance = appearance
        bar?.compactAppearance = appearance
    } else {
        // Fallback on earlier versions
    }
}