快照如何干扰父/子关系?

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.viewUIScrollView,截图的代码是

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)

【讨论】:

以上是关于快照如何干扰父/子关系?的主要内容,如果未能解决你的问题,请参考以下文章

如何从关系中删除子对象或父对象?

WPF 如何清除父控件与子控件的关系

如何表示同一类型的父属性和多个子属性之间的关系?

如何在不更新具有多对多关系的子实体的情况下保留父实体?

跨复杂父/子/父/子关系的 LINQ 查询

Restkit/Core Data 关系映射,实体到相同类型的实体(父/子)