iOS 17重写traitCollection的get方法导致闪退

UITabBar 在 iOS 11 后在 iPad 上图标和文字是左右显示,为了和iPhone 保持一致,强制上下排布,重写了 traitCollection 方法,但是这个方法在 iOS17 上闪退了,闪退信息如下:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'A trait environment returned a trait collection with unspecified values for traits that are not allowed to be unspecified. This is a serious application bug and will cause undefined behavior. This issue may be caused by your class overriding the traitCollection property getter, which is not supported. Make sure to use the appropriate API if you are trying to override traits. Trait Environment: <UITabBar: 0x13012b730; frame = (0 1129; 834 65); hidden = YES; autoresize = W+TM; gestureRecognizers = <NSArray: 0x600000cc3300>; layer = <CALayer: 0x600000292960>>; Trait Collection: <UITraitCollection: 0x129c11900; VerticalSizeClass = Compact>'
*** First throw call stack:
(
0 CoreFoundation 0x00007ff80048d28d __exceptionPreprocess + 242
1 libobjc.A.dylib 0x00007ff800057894 objc_exception_throw + 48
2 Foundation 0x00007ff800da2e27 -[NSMutableDictionary(NSMutableDictionary) classForCoder] + 0
3 UIKitCore 0x000000012a82b853 _UIGetCurrentFallbackTraitCollection + 383
4 UIKitCore 0x000000012a827d27 +[UITraitCollection _currentTraitCollectionWithFallback:markFallback:] + 367
5 UIKitCore 0x000000012b463dde -[UIView(Hierarchy) _setBackgroundColor:] + 73
6 UIKitCore 0x000000012a0c7ac9 -[UITabBarButton _updateToMatchCurrentState] + 927
7 UIKitCore 0x000000012a0c5c6b -[UITabBarButton setItemVibrantEffect:] + 68
8 UIKitCore 0x000000012a0bd89d __54-[_UITabBarVisualProviderLegacyIOS _layoutTabBarItems]_block_invoke + 313
9 CoreFoundation 0x00007ff8003ed6b1 __NSARRAY_IS_CALLING_OUT_TO_A_BLOCK__ + 7
10 CoreFoundation 0x00007ff8004d4c01 -[__NSSingleObjectArrayI enumerateObjectsWithOptions:usingBlock:] + 80
11 UIKitCore 0x000000012a0bd62e -[_UITabBarVisualProviderLegacyIOS _layoutTabBarItems] + 2420
12 UIKitCore 0x000000012a0be66c -[_UITabBarVisualProviderLegacyIOS layoutSubviews] + 94
13 UIKitCore 0x000000012a0b2b92 -[UITabBar layoutSubviews] + 41
14 UIKitCore 0x000000012b47cd07 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2141
15 QuartzCore 0x00007ff808ff9c71 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 527
16 QuartzCore 0x00007ff809005a33 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 67
17 QuartzCore 0x00007ff808f07464 _ZN2CA7Context18commit_transactionEPNS_11TransactionEdPd + 706
18 QuartzCore 0x00007ff808f419ba _ZN2CA11Transaction6commitEv + 728
19 UIKitCore 0x000000012adcfa0b __34-[UIApplication _firstCommitBlock]_block_invoke_2 + 34
20 CoreFoundation 0x00007ff8003e9b06 __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
21 CoreFoundation 0x00007ff8003e92b9 __CFRunLoopDoBlocks + 391
22 CoreFoundation 0x00007ff8003e3b98 __CFRunLoopRun + 940
23 CoreFoundation 0x00007ff8003e3409 CFRunLoopRunSpecific + 557
24 GraphicsServices 0x00007ff80a650187 GSEventRunModal + 137
25 UIKitCore 0x000000012adb03a2 -[UIApplication _run] + 972
26 UIKitCore 0x000000012adb4e10 UIApplicationMain + 123
27 HaoJiaZhang 0x00000001104522d8 main + 104
28 dyld 0x0000000113c433ee start_sim + 10
29 ??? 0x0000000118ff23a6 0x0 + 4714341286
)
libc++abi: terminating due to uncaught exception of type NSException

解决办法

override open var traitCollection: UITraitCollection {
if UIDevice.current.userInterfaceIdiom == .pad {
if #available(iOS 17.0, *) {
self.traitOverrides.horizontalSizeClass = .compact
} else {
return UITraitCollection(horizontalSizeClass: .compact)
}
}
return super.traitCollection
}
- (UITraitCollection *)traitCollection {

if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) {

if (@available(iOS 17.0, *)){
self.traitOverrides.horizontalSizeClass = UIUserInterfaceSizeClassCompact;
}else{
return [UITraitCollection traitCollectionWithVerticalSizeClass:UIUserInterfaceSizeClassCompact];
}
}

return [super traitCollection];

}

参考文章
https://developer.apple.com/forums/thread/738678