10

在 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 中编译的应用程序仍会以正常方式运行,只是在编译后由于某种原因发生变化。这是有意的,我将如何恢复原始行为?

4

2 回答 2

12

这是 iOS 13 的预期行为。

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

这很糟糕的原因是因为每个人目前都计划了他们所有的 UI 没有这种行为。所以新的行为应该是选择加入而不是强迫每个人都选择退出(即更改破坏了每个人的代码,如果你要破坏每个人的代码,至少你应该清楚如何保持久经考验的真实行为过去 10 年)。

与您的情况一样,结果看起来很糟糕。在我的情况下,结果看起来也很糟糕。

苹果没有给出答案,但说你应该使用

- scrollEdgeAppearance

从 UINavigationBar 以控制当内容顶部对齐到导航栏底部时栏的外观......在我的情况下,这个方法返回 nil 但我目前不确定我们应该如何使用这个。

这似乎也在这里讨论:

iOS 13 中 UISplitViewController 的详细信息窗格中的新 UINavigationBar 外观

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

- (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 对象自己创建这些条,因此您不会获得子类。

于 2019-06-21T04:43:39.453 回答
7

dbquarrel 解决方案的 Swift 版本。

首先声明你的 textAttributes:

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

在 a 中使用这些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
    }
}
于 2019-06-21T15:23:46.343 回答