Xcode 9 / iOS 11 "CALayer bounds contains NaN: [nan 0; nan 0]" 当使用嵌套的 UINavigationController 和 UITabBarController 弹出视图控制器时
Xcode 9 / iOS 11 "CALayer bounds contains NaN: [nan 0; nan 0]" when popping view controller with nested UINavigationController and UITabBarController
我正在为 Xcode 9、Swift 4、iOS 11 和 iPhone X 更新我的申请。它似乎一路相对顺利,但每当我按下后退按钮时,我的应用程序就会崩溃。我可以毫无问题地前进 3-4 个屏幕,但第一个后退按钮总是使应用程序崩溃。它不需要模拟器 运行 作为 iPhone X.
它似乎没有深入到我的堆栈跟踪代码中,所以我认为这是我正在弹出的视图控制器的重绘阶段,但我不确定。
因为我做了很多自定义绘图,因为 UITableViews 和 UIViews 周围有自定义阴影,所以我在除以变量的所有位置设置断点,但没有命中。所以似乎不是我的代码按零计算。
*** Terminating app due to uncaught exception 'CALayerInvalidGeometry', reason: 'CALayer bounds contains NaN: [nan 0; nan 0]'
*** First throw call stack:
(
0 CoreFoundation 0x000000010af711cb __exceptionPreprocess + 171
1 libobjc.A.dylib 0x000000010a8d3f41 objc_exception_throw + 48
2 CoreFoundation 0x000000010afe5b95 +[NSException raise:format:] + 197
3 QuartzCore 0x0000000109424424 _ZN2CA5Layer10set_boundsERKNS_4RectEb + 230
4 QuartzCore 0x0000000109414c29 -[CALayer setBounds:] + 251
5 UIKit 0x0000000107267439 __27-[_UILabelLayer setBounds:]_block_invoke + 80
6 UIKit 0x000000010726717b -[_UILabelLayer _setFrameOrBounds:settingAction:] + 23
7 UIKit 0x00000001072673d8 -[_UILabelLayer setBounds:] + 155
8 QuartzCore 0x000000010941537c -[CALayer setFrame:] + 630
9 UIKit 0x0000000107267319 __26-[_UILabelLayer setFrame:]_block_invoke + 80
10 UIKit 0x000000010726717b -[_UILabelLayer _setFrameOrBounds:settingAction:] + 23
11 UIKit 0x00000001072672b8 -[_UILabelLayer setFrame:] + 155
12 UIKit 0x0000000106c4cf1e -[UIView(Geometry) setFrame:] + 368
13 UIKit 0x0000000106e4ec40 -[UILabel setFrame:] + 141
14 UIKit 0x0000000106fff254 -[UIButton _layoutTitleView] + 248
15 UIKit 0x0000000106fff3cf -[UIButton layoutSubviews] + 250
16 UIKit 0x0000000106c6c551 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1331
17 QuartzCore 0x000000010941b4ba -[CALayer layoutSublayers] + 153
18 QuartzCore 0x000000010941f5a9 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 401
19 QuartzCore 0x00000001093a81cd _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 365
20 QuartzCore 0x00000001093d3ae4 _ZN2CA11Transaction6commitEv + 500
21 UIKit 0x0000000106b97f4a _UIApplicationFlushRunLoopCATransactionIfTooLate + 167
22 UIKit 0x00000001074ef960 __handleEventQueueInternal + 6894
23 CoreFoundation 0x000000010af142b1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
24 CoreFoundation 0x000000010afb3d31 __CFRunLoopDoSource0 + 81
25 CoreFoundation 0x000000010aef8c19 __CFRunLoopDoSources0 + 185
26 CoreFoundation 0x000000010aef81ff __CFRunLoopRun + 1279
27 CoreFoundation 0x000000010aef7a89 CFRunLoopRunSpecific + 409
28 GraphicsServices 0x00000001104e59c6 GSEventRunModal + 62
29 UIKit 0x0000000106b9dd30 UIApplicationMain + 159
30 My Customer's Application Name 0x000000010475f087 main + 55
31 libdyld.dylib 0x000000010cfedd81 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
因为我在修复它时已经完成了所有输入(它总是有助于向其他人表达你的问题;-))我决定 post 我的问题和答案。
我有一个导航设置,其中标签栏嵌套在导航控制器中。我知道我们被警告过不要这样做,但是,嘿,它一直都很有效。通过外观代理设置大标题视图后如下:
if #available(iOS 11.0, *) {
UINavigationBar.appearance().prefersLargeTitles = true
}
返回时屏幕开始崩溃。将其改回 false
使所有问题都消失了。
TL;DR: 在我们的例子中,这个 iOS 11 / Xcode 9 错误是由添加自定义 UILabel
的代码引起的到 UINavigationItem.titleView
。
此代码是使用臭名昭著的混合技术编写的,该技术覆盖了 -[UINavigationItem setTitle:]
选择器 - 在调用原始 setTitle:
方法的同时,我们的开发人员还将具有相同标题的自定义标签设置为 UINavigationItem.titleView
属性。问题是当使用 setTitle:nil
调用导航项时,空的 UILabel
被添加到具有 zero-rect 尺寸的 .titleView
,这导致 UIKit 崩溃。如果 title:
参数为零,立即的快速修复是停止设置 .titleView
。 long-term 修复将从应用程序中删除 swizzling。
P.S。我打开了一个雷达,请求改进此错误的错误消息:
我遇到了同样的问题,因为工具栏标题在之前的 VC 中设置为空字符串。一旦我用至少某种文本设置了所有标题,我就不再崩溃了。同样,这仅适用于 iOS 11 和 Xcode 9,在以前的版本中有效。
当我为 NavigationBar 设置指定 ViewController 时发生了这种情况,首选大标题 = true。
我用 pjapple15 的方法解决了它。我只是在前一个 ViewController 的 NavigationBar 中设置了一个像空字符串 = " " 这样的标题,它工作正常。
而且我还在NavigationBar.titleView,中添加了一个SearchBar,之后我就设置了NavigationItem.title = " ".
我正在为 Xcode 9、Swift 4、iOS 11 和 iPhone X 更新我的申请。它似乎一路相对顺利,但每当我按下后退按钮时,我的应用程序就会崩溃。我可以毫无问题地前进 3-4 个屏幕,但第一个后退按钮总是使应用程序崩溃。它不需要模拟器 运行 作为 iPhone X.
它似乎没有深入到我的堆栈跟踪代码中,所以我认为这是我正在弹出的视图控制器的重绘阶段,但我不确定。
因为我做了很多自定义绘图,因为 UITableViews 和 UIViews 周围有自定义阴影,所以我在除以变量的所有位置设置断点,但没有命中。所以似乎不是我的代码按零计算。
*** Terminating app due to uncaught exception 'CALayerInvalidGeometry', reason: 'CALayer bounds contains NaN: [nan 0; nan 0]'
*** First throw call stack:
(
0 CoreFoundation 0x000000010af711cb __exceptionPreprocess + 171
1 libobjc.A.dylib 0x000000010a8d3f41 objc_exception_throw + 48
2 CoreFoundation 0x000000010afe5b95 +[NSException raise:format:] + 197
3 QuartzCore 0x0000000109424424 _ZN2CA5Layer10set_boundsERKNS_4RectEb + 230
4 QuartzCore 0x0000000109414c29 -[CALayer setBounds:] + 251
5 UIKit 0x0000000107267439 __27-[_UILabelLayer setBounds:]_block_invoke + 80
6 UIKit 0x000000010726717b -[_UILabelLayer _setFrameOrBounds:settingAction:] + 23
7 UIKit 0x00000001072673d8 -[_UILabelLayer setBounds:] + 155
8 QuartzCore 0x000000010941537c -[CALayer setFrame:] + 630
9 UIKit 0x0000000107267319 __26-[_UILabelLayer setFrame:]_block_invoke + 80
10 UIKit 0x000000010726717b -[_UILabelLayer _setFrameOrBounds:settingAction:] + 23
11 UIKit 0x00000001072672b8 -[_UILabelLayer setFrame:] + 155
12 UIKit 0x0000000106c4cf1e -[UIView(Geometry) setFrame:] + 368
13 UIKit 0x0000000106e4ec40 -[UILabel setFrame:] + 141
14 UIKit 0x0000000106fff254 -[UIButton _layoutTitleView] + 248
15 UIKit 0x0000000106fff3cf -[UIButton layoutSubviews] + 250
16 UIKit 0x0000000106c6c551 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1331
17 QuartzCore 0x000000010941b4ba -[CALayer layoutSublayers] + 153
18 QuartzCore 0x000000010941f5a9 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 401
19 QuartzCore 0x00000001093a81cd _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 365
20 QuartzCore 0x00000001093d3ae4 _ZN2CA11Transaction6commitEv + 500
21 UIKit 0x0000000106b97f4a _UIApplicationFlushRunLoopCATransactionIfTooLate + 167
22 UIKit 0x00000001074ef960 __handleEventQueueInternal + 6894
23 CoreFoundation 0x000000010af142b1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
24 CoreFoundation 0x000000010afb3d31 __CFRunLoopDoSource0 + 81
25 CoreFoundation 0x000000010aef8c19 __CFRunLoopDoSources0 + 185
26 CoreFoundation 0x000000010aef81ff __CFRunLoopRun + 1279
27 CoreFoundation 0x000000010aef7a89 CFRunLoopRunSpecific + 409
28 GraphicsServices 0x00000001104e59c6 GSEventRunModal + 62
29 UIKit 0x0000000106b9dd30 UIApplicationMain + 159
30 My Customer's Application Name 0x000000010475f087 main + 55
31 libdyld.dylib 0x000000010cfedd81 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
因为我在修复它时已经完成了所有输入(它总是有助于向其他人表达你的问题;-))我决定 post 我的问题和答案。
我有一个导航设置,其中标签栏嵌套在导航控制器中。我知道我们被警告过不要这样做,但是,嘿,它一直都很有效。通过外观代理设置大标题视图后如下:
if #available(iOS 11.0, *) {
UINavigationBar.appearance().prefersLargeTitles = true
}
返回时屏幕开始崩溃。将其改回 false
使所有问题都消失了。
TL;DR: 在我们的例子中,这个 iOS 11 / Xcode 9 错误是由添加自定义 UILabel
的代码引起的到 UINavigationItem.titleView
。
此代码是使用臭名昭著的混合技术编写的,该技术覆盖了 -[UINavigationItem setTitle:]
选择器 - 在调用原始 setTitle:
方法的同时,我们的开发人员还将具有相同标题的自定义标签设置为 UINavigationItem.titleView
属性。问题是当使用 setTitle:nil
调用导航项时,空的 UILabel
被添加到具有 zero-rect 尺寸的 .titleView
,这导致 UIKit 崩溃。如果 title:
参数为零,立即的快速修复是停止设置 .titleView
。 long-term 修复将从应用程序中删除 swizzling。
P.S。我打开了一个雷达,请求改进此错误的错误消息:
我遇到了同样的问题,因为工具栏标题在之前的 VC 中设置为空字符串。一旦我用至少某种文本设置了所有标题,我就不再崩溃了。同样,这仅适用于 iOS 11 和 Xcode 9,在以前的版本中有效。
当我为 NavigationBar 设置指定 ViewController 时发生了这种情况,首选大标题 = true。
我用 pjapple15 的方法解决了它。我只是在前一个 ViewController 的 NavigationBar 中设置了一个像空字符串 = " " 这样的标题,它工作正常。
而且我还在NavigationBar.titleView,中添加了一个SearchBar,之后我就设置了NavigationItem.title = " ".