【问题标题】:Is this new navigation bar behaviour in xcode 11 beta a bug or intended?xcode 11 beta 中的这种新导航栏行为是错误还是有意的?
【发布时间】:2019-06-06 18:07:19
【问题描述】:

在 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 上一个而另一个在 iOS 12(或更早版本)上?
  • 一个在我的 iOS 13 物理设备上,另一个在 ios 12 模拟器上。但是我的 iOS 13 设备上有另一个应用程序,它以完全相同的方式(相同的代码)处理导航栏,并且在我的 iOS 13 设备上正常工作,我怀疑如果我在 Xcode 11 上编译该应用程序,它会改变。
  • @rmaddy 刚刚测试,我的其他应用在 ios 13 设备上运行良好,在 Xcode 11 上编译了代码,导航栏背景消失了。
  • 可能是 Apple 的意图。如果您想保留旧的行为,只需为您的导航栏设置一个模糊的背景。 (通过模糊,我的意思是 setBackgroundImage 的图像由部分透明的颜色制成)。不要忘记 shadowImage。
  • Cœur,鉴于此站点,使用解决方案发布代码比“做这个然后做那个”更好。

标签: swift navigationbar xcode11


【解决方案1】:

这是 iOS 13 的预期行为。

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

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

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

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

- scrollEdgeAppearance

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

这似乎也在这里讨论过:

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

【讨论】:

  • 谢谢,它有效,但我注意到我设置的textattributes 不起作用,所以我无法将标题颜色从默认的黑色更改!
  • 我现在也遇到了同样的问题,昨晚我得到了这个为我工作,现在发现我也无法更改颜色。也许 navBar.scrollEdgeAppearance.backgroundColor 和 navBar.scrollEdgeAppearance.titleTextAttributes 是现在需要调整的东西。到目前为止,这似乎是一件非常愚蠢的事情。
【解决方案2】:

dbquarrel 解决方案的 Swift 版本。

首先声明你的 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
    }
}

【讨论】:

  • 彼得鲁珀特解决方案只有在我向下滚动视图时才对我有效
  • @frantenerelli 更新了答案以添加更多细节并希望解决该问题。
猜你喜欢
  • 2020-02-07
  • 1970-01-01
  • 2015-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-28
相关资源
最近更新 更多