UIBarButtonItem 工作但在 Xcode11 和 Xcode12 下不可见

UIBarButtonItem working but not visible with Xcode11 and Xcode12

将我们的应用程序从 Xcode10 迁移到 Xcode12 后,我们发现 UIBarButtonItems 存在问题。其中一些不可见但仍在工作。

我们能够更具体地针对以下目标:

查看“层次结构视图”时,项目及其图标在那里,但未显示在设备上。 我们没有看到显示或不显示项目的任何差异,这有助于理解问题。

下面的截图是:

  1. 故事板
  2. 从图标启动后 iPad 出现问题
  3. 查看问题的层次结构

此处提供更多屏幕截图(比较):https://imgur.com/a/7Dcyvir

有没有人见过 Xcode11 或 Xcode12 的类似行为? 知道我们可以尝试什么,或者它是否是需要报告以进行修复的 Xcode 问题?

在此先感谢您的帮助!

System Font Symbols 自推出以来已经发生了变化,因此可以称为 SF Symbols 1 和 SF Symbols 2,其中 SF Symbols 1 是 SF Symbols 2(支持多色符号)的一部分,有些也已详细更改。

一些符号(实际上很多)甚至在 iOS 13 之前就可用了,但一般来说文档说...

SF Symbols are available in iOS 13 and later, macOS 11 and later, watchOS 6 and later, and tvOS 13 and later.

所以您尝试使用的特定符号 arrow.clockwise 是 SF Symbol 1 集合的一部分,并且是 iOS 13 之前可用的符号之一 Refresh Symbol .但是由于它们是 re-introduced 作为 SF Symbols 你 运行 在这里遇到麻烦。在 iOS 13 以下的目标中,它们(一些)显示为 UIKit 控件的一部分,在 iOS 12 以上的目标中,它们是系统字体符号,它们尊重 UI 的多个参数,例如darkMode, lightMode, anyMode, FontWeight, localization 等等。

来自 Apple 文档.. Creating Custom Symbols

If you need a symbol that isn't provided by SF Symbols, you can create your own. The SF Symbols app lets you export a symbol as a template in a reusable, vector-based file format.

还有

When you export a symbol introduced in SF Symbols 2 as an SVG template and bundle it with your app, you can use it in apps that target iOS 13, Mac Catalyst 13, tvOS 13, or watchOS 6, but without the benefit of SF Symbol 2 features like multicolor support and automatic localization.

提到的用于导出和验证 SVG 格式SF 符号的SF Symbols 工具可以找到here
查看SF Symbols 1.1 应用程序如何 需要 macOS 10.14.4 或更高版本看起来像。

arrow.clockwise 符号未标有 (i),这会告诉您有关版权和其他您必须尊重的信息。

导出的 SVG 文件包含所有加权符号和布局指南,以保持此 SF Symbol 功能,并将帮助您使用它开发图形。格式解释 here

除非您的目标是 OSX 10.15 或 iOS 13,否则无法将此 SVG 文件按原样放入您的 Apps Assets 中。如果您尝试在下面执行此操作,编译器会警告您提到的版本。但是您可以在 Sketch 或类似工具中打开它以编辑 SVG 数据并生成图形作为解决方法。我建议这样做并将此图形加载到您的 UI 元素中。

从 iOS 13 开始使用系统字体符号以及如何加载它们的说明 here

正如您在代码中以编程方式设置 UIBarButtonItem 一样,它也可以这样写......

UIBarButtonItem *barBtn = nil;
if (@available(iOS 13.0, *)) {
    UITraitCollection *trait = [UITraitCollection currentTraitCollection];
    barBtn = [[UIBarButtonItem alloc] initWithImage:[UIImage systemImageNamed:@"arrow.clockwise" compatibleWithTraitCollection:trait] style:UIBarButtonItemStylePlain target:self action:@selector(refreshMethodHere)];
} else {
    barBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(refreshMethodHere)];
}

我们无法从头开始在另一个应用程序中重现。 因此,我们添加以相反的方式进行:剥离我们当前的应用程序,直到问题不再存在。 第一步是拆解到只有一个 AppDelegate 和一段简单的代码,但问题仍然存在。 我们从 cocoapods 中删除了所有依赖项,但问题仍然存在。 我们最终删除了一个我们直接添加到项目中的框架,它是罪魁祸首!

所述框架是BiometricSDK(来自IDEMIA)。我们将向他们发送邮件,以了解他们是否知道此问题,以及他们是否已修复/将在较新版本中修复它。它不是 open-source 所以我不知道具体问题是什么,我唯一的猜测是他们以某种方式改变了 UIBarButtonItems 的外观(但我不确定他们的代码是如何调用的,因为我们删除了对它同时剥离应用程序)。

当您将 UIBarButtonItem 的标题文本属性 foregroundColor 设置为 UIColor.clear 时,可能会出现此问题。

您可以直接这样做,例如:

navigationItem.rightBarButtonItem?.setTitleTextAttributes([.foregroundColor: UIColor.clear], for: .normal)

或者通过修改UIBarButtonItem的外观,例如:

UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.clear], for: .normal)

检查你的代码,也许你有这样的设置。