快照如何干扰父/子关系?
Posted
技术标签:
【中文标题】快照如何干扰父/子关系?【英文标题】:How does snapshotting interfere with parent/child relationships? 【发布时间】:2015-08-12 09:48:15 【问题描述】:总结
-
将
childVC
添加到parentVC
快照childVC.view
它出错了。
为什么?
情况
我刚刚遇到了一个奇怪的行为,我想知道它是正常的还是错误的。
我有一个视图控制器childVC
,它是parentVC
的子级。创建父/子关系时,我的代码是
[parentVC addChildViewController:childVC] ;
[parentVC.view addSubview:childVC.view] ;
[childVC didMoveToParentViewController: parentVC] ;
几行进一步,我想创建childVC.view
的快照。我的代码是
UIView * view = childVC.view ;
UIGraphicsBeginImageContextWithOptions(view.contentSize, NO, 0);
[...]
[view drawViewHierarchyInRect:view.bounds
afterScreenUpdates:YES];
image = UIGraphicsGetImageFromCurrentImageContext();
[...]
UIGraphicsEndImageContext();
错误
然后我有错误:
* 由于未捕获的异常“UIViewControllerHierarchyInconsistency”而终止应用程序,原因:“子视图” 控制器:应该有父级 视图控制器:(null)但实际父级是:' * 第一次抛出调用堆栈:( 0 CoreFoundation 0x0260b466 __exceptionPreprocess + 182 1 libobjc.A.dylib 0x02290a97 objc_exception_throw + 44 2 核心基础 0x0260b38d +[NSException raise:format:] + 141 3 UIKit 0x01136710 -[UIView(层次结构) _associatedViewControllerForwardsAppearanceCallbacks:performHierarchyCheck:isRoot:] + 352 4 UIKit 0x01136b13 -[UIView(Hierarchy) _willMoveToWindow:withAncestorView:] + 285 5 UIKit 0x0114330a -[UIView(内部) _addSubview:positioned:relativeTo:] + 511 6 UIKit 0x01136252 -[UIView(Hierarchy) addSubview:] + 56 7 UIKit 0x0114ab0e +[_UIReplicantView _pendingSnapshotOfTarget:snapshotBlock:] + 584 8 UIKit 0x011312fe -[UIView drawViewHierarchyInRect:afterScreenUpdates:] + 287
问题
为什么会这样?我可以解决这个问题吗?
更多详情
其实childVC.view
是UIScrollView
,截图的代码是
UIScrollView * scrollView = (UIScrollView *)childVC.view;
UIGraphicsBeginImageContextWithOptions(scrollView.contentSize, NO, 0);
CGPoint savedContentOffset = scrollView.contentOffset;
CGRect savedFrame = scrollView.frame;
scrollView.contentOffset = CGPointZero;
scrollView.frame = CGRectMake(0,
0,
scrollView.contentSize.width,
scrollView.contentSize.height);
[scrollView drawViewHierarchyInRect:scrollView.bounds
afterScreenUpdates:YES];
image = UIGraphicsGetImageFromCurrentImageContext();
scrollView.contentOffset = savedContentOffset;
scrollView.frame = savedFrame;
UIGraphicsEndImageContext();
也许这会带来很大的不同。
【问题讨论】:
已经 3 岁了,但今天在 Swift 4 中发生在我身上。从那以后你的问题解决了吗? 不,抱歉。祝你好运。 这是最奇怪的错误!它对我来说只工作一次,并在随后的快照中崩溃 我遇到了完全相同的崩溃,但情况不同。当您对没有窗口的视图进行快照时会发生这种情况(例如view.window == nil
)
我也遇到过这个问题。我的解决方案是从父级快照中删除子级,然后将其添加回父级。我猜孩子 viewController 就像我的孩子 - 请不要快照!
【参考方案1】:
我今天在使用 UIViewControllerAnimatedTransitioning
实现自定义转换时遇到了同样的问题。问题是,当我尝试对子视图控制器进行快照时,它的父视图还不是视图层次结构的一部分。
解决方案是确保在您尝试对子视图进行快照之前,已将父视图添加到视图层次结构中。就我而言,我只需要先将“to”视图控制器添加到transitionContext.containerView
。
根据您的代码 sn-p,我无法判断您何时尝试拍摄快照。但是如果在viewDidAppear()
之前,可能就不行了。
【讨论】:
你救了我的命!在自定义转换中也有问题,我只是没有收到任何错误消息或崩溃,只是布局混乱。添加到容器首先解决了它。非常感谢!【参考方案2】:我在使用view.snapshotView(afterScreenUpdates: true)
捕获子视图控制器的视图然后从父视图中删除它时遇到了这个崩溃。
对我来说,将false
传递给afterScreenUpdates
解决了这个问题。
【讨论】:
【参考方案3】:也许您的父视图控制器正在被释放,因此异常消息中的(null)
?
【讨论】:
以上是关于快照如何干扰父/子关系?的主要内容,如果未能解决你的问题,请参考以下文章