在调试 custom view 时出现错误:
Runtime: iOS 14.5 (18E182) - DeviceType: IBSimDeviceTypeiPad2x
进入 ~/Library/Logs/DiagnosticReports 目录,查看 IBDesignablesAgent-iOS 开头的日志,发现:
1 libswiftCore.dylib 0x0000000107576509 closure #1 in closure #1 in _assertionFailure(_:_:file:line:flags:) + 105
2 libswiftCore.dylib 0x00000001075762a9 closure #1 in _assertionFailure(_:_:file:line:flags:) + 121
3 libswiftCore.dylib 0x0000000107575f6c _assertionFailure(_:_:file:line:flags:) + 428
4 com.iconmobile.henkel.salonlab.debug 0x00000002082ede2e static UIFont.font(type:size:) + 302 (FontStyling.swift:14)
5 com.iconmobile.henkel.salonlab.debug 0x000000020815e6de ChooseStatusLabel.commonTextUIUpdate() + 206
代码定位到这里:
titleLabel.font = .font(type: .apercuRegular, size: 18)
原因很简单了,DesignablesAgent 加载不了自定义字体。
此类错误的一般原因都是 custom view 的 init() 方法中有错误代码,比如加载不了图片资源(IB bug)或者自定义字体。
这个 app 运行时很正常,并没有出现加载不了字体的情况。为什么 DesignablesAgent 会加载不了自定义字体 ?原因如下:
IB 在渲染 costom view 时,使用一个 DesignablesAgent 的组件。这个组件在渲染时不会加载 App 的 bundle(main bundle)。因此你在 init 方法(不管哪个init 方法)中,如果有代码加载了图片资源或custom字体,那将返回 nil,正常情况下不会有问题,因为无论是 UIImage 的 image 属性,还是 UILabel 的 font 属性,都是 optional 的。而且哪怕是 init 时加载不到,但在 updateDisplay 时还是会重新加载(如果你通过 IB 设置了这些属性),所以图片、字体还是可以正常显示的。
但是如果你对这些资源进行了强制解包(使用! 进行强制解包),比如:
static func font(type: FontType, size: Float) -> UIFont {
UIFont(name: type.rawValue, size: CGFloat(size))!
}
当然就会导致 Designables Agent crashed。因此需要将强制解包修改为:
UIFont(name: type.rawValue, size: CGFloat(size)) ?? UIFont.systemFont(ofSize: CGFloat(size))