UIBarButtonItem有效,但在Xcode11和Xcode12中不可见

问题描述

将我们的应用程序从Xcode10迁移到Xcode12后,我们发现UIBarButtonItems出现问题。其中一些是不可见的,但仍可以使用。

我们能够更具体地定位以下目标:

  • iOS12上的Xcode10.3:没有问题
  • iOS13上的Xcode10.3发行版:没问题
  • iOS14上的Xcode10.3发行版:没问题
  • iOS12上的Xcode11.7:没有问题
  • iOS13上的Xcode11.7:存在问题
  • iOS12上的Xcode12.0.1:没有问题
  • iOS13上的Xcode12.0.1:存在问题
  • iOS14上的Xcode12.0.1:存在问题
  • 问题出现在Debug和Release中
  • 当我们从Xcode运行应用程序时,没有出现问题
  • 仅当我们退出应用程序并直接从设备再次启动它时,问题才会出现
  • 仅当UIBarButtonItem是带有图标的系统项时出现问题,例如:刷新,添加,...
  • 问题没有出现,UIBarButtonItem是带有文本的系统项,例如:Edit,Close,...
  • 问题没有出现,UIBarButtonItem自定义为资产中的图像
  • 如果我以编程方式执行UIBarButtonItem系统,也会出现问题

查看“层次结构视图”时,该项目及其图标在那里,但未在设备上显示。 无论显示与否,我们都看不到任何有助于理解问题的区别。

屏幕截图下面是:

  1. 故事板
  2. 从图标启动后在iPad上发布
  3. 查看问题的层次结构

更多屏幕截图(比较)可在此处找到:https://imgur.com/a/7Dcyvir

Storyboard

Issue on iPad after launch from icon

View hierarchy of the issue

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

在此先感谢您的帮助!

解决方法

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

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

,

系统字体符号自引入以来已进行了更改,因此它们可以称为SF符号1和SF符号2,其中SF符号1是SF符号2的一部分(支持多色符号),并且其中的一些符号也已更改细节。

甚至在iOS 13之前,某些符号(实际上是很多符号)就已经可用了,但总的来说,文档说...

SF符号在iOS 13和更高版本,macOS 11和更高版本,watchOS 6和更高版本以及tvOS 13和更高版本中可用。

因此,您尝试使用的特定符号arrow.clockwise是SF Symbol 1 Collection的一部分,并且甚至是在iOS 13之前都可以使用的Refresh符号之一。但是,由于将它们重新引入为SF符号,您在这里遇到了麻烦。在iOS 13以下的目标中,它们(某些)显示为UIKit控件的一部分,而在iOS 12以上的目标中,它们是系统字体符号,它们尊重UI的多个参数,例如darkMode,lightMode,anyMode,FontWeight,本地化等。

摘自Apple文档。.Creating Custom Symbols

如果需要SF Symbols未提供的符号,则可以创建自己的符号。 SF Symbols应用程序允许您以可重复使用的,基于矢量的文件格式将符号导出为模板

还有

当您将SF Symbols 2中引入的符号导出为 SVG模板并与您的应用捆绑在一起时,可以在针对iOS 13,Mac Catalyst 13,tvOS 13或iOS的应用中使用它。 watchOS 6,但是没有SF Symbol 2的优势,例如多色支持和自动本地化。

提到的用于导出和验证 SVG格式SF符号的SF Symbols工具可以在here中找到。
了解SF Symbols 1.1应用如何 需要使用macOS 10.14.4或更高版本。

Screenshot SF Symbols 1.1 app

arrow.clockwise符号没有标记(i),它会告诉您版权和其他您必须遵守的信息。

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

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

here

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

并且正如您确实以编程方式在代码中设置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)];
}
,

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

您可以直接执行此操作,例如:

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

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

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

检查您的代码,也许您在某处有这样的设置。