当我尝试关闭模式时 iOS 崩溃

Posted

技术标签:

【中文标题】当我尝试关闭模式时 iOS 崩溃【英文标题】:iOS crash when I try to dismiss a modal 【发布时间】:2017-06-22 08:41:28 【问题描述】:

我用模态过渡动画模态控制器。但是当我尝试关闭控制器时,程序崩溃了。 Xcode 没有记录任何消息。

我的过渡动画有问题。当我删除过渡代码时,它运行良好。

那么我的代码有什么问题?

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext 
    _transitionContext = transitionContext;
    UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
    UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
    CALayer *toVcLayer = [CALayer layer];
    toVcLayer.frame = toView.layer.frame;
    [toVcLayer addSublayer:toView.layer];

    _transformLayer = [CATransformLayer layer];
    _transformLayer.frame = [UIScreen mainScreen].bounds;
    [_transformLayer addSublayer:fromView.layer];
    CATransform3D ct = CATransform3DIdentity;
    ct = CATransform3DMakeTranslation(0.0, 0.0, -1.0);
    ct = CATransform3DRotate(ct, M_PI, 0.0, 1.0, 0.0);
    toVcLayer.transform = ct;
    [_transformLayer addSublayer:toVcLayer];

    CATransform3D at = CATransform3DIdentity;
    at = CATransform3DRotate(at, M_PI, 0.0, 1.0, 0.0);
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];
    animation.toValue = [NSValue valueWithCATransform3D:at];
    animation.duration = 1.0;
    animation.delegate = self;
    [_transformLayer addAnimation:animation forKey:nil];

    [transitionContext.containerView.layer addSublayer:_transformLayer];


- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag 
    [_transitionContext.containerView addSubview:[_transitionContext viewForKey:UITransitionContextToViewKey]];
    [_transitionContext completeTransition:YES];

【问题讨论】:

【参考方案1】:

问题可能在于在其他层之间移动层。您正在尝试在其他地方插入已经有超级层的层。我不知道为什么它在展示时还没有崩溃,但它在关闭时就不足为奇了。

当关闭视图控制器时,它们的状态是不同的。主要是toView已经是containerView的子视图。毕竟是fromView。随着您的代码视图/层层次结构变得非常纠结,最终导致崩溃。

解决方案非常简单。而不是创建单独的transformLayer 来保存其他图层并为其设置动画。分别为每一层设置动画。示例:

-(void)animateTransition(id<UIViewControllerContextTransitioning>)transitionContext 
    _transitionContext = transitionContext;
    UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
    UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];

    if (toView.superview == nil)
        [transitionContext.containerView addSubview:toView];

    const NSTimeInterval duration = 1.0;
    const CGFloat translationX = 400.0;

    toView.layer.transform = CATransform3DMakeTranslation(translationX, 0.0, 0.0);

    CABasicAnimation *toAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
    toAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
    toAnimation.duration = duration;
    toAnimation.delegate = self;

    CABasicAnimation *fromAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
    fromAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeTranslation(-translationX, 0.0, 0.0];
    fromAnimation.duration = duration;

    [fromView addAnimation:fromAnimation forKey:nil];
    [toView addAnimation:toAnimation forKey:nil];


-(void)animationDidStop:(CAAnimation*)anim finished:(BOOL)flag 
    [_transitionContext completeTransition:YES];

【讨论】:

谢谢!这个问题我纠结了很久。

以上是关于当我尝试关闭模式时 iOS 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

关闭纵向视图控制器时应用程序崩溃

应用程序在后台模式下仅在 iOS 13 上崩溃

AsyncSocket 在 iPad 的睡眠模式下崩溃

ios 应用程序在调试模式下完美运行,但在发布时崩溃

执行 GetParent() 时崩溃。关闭无模式对话框

Unity 集成到原生 iOS 应用程序中。关闭 Unity 部件并尝试重新打开它时应用程序崩溃