iOS 当我尝试关闭模态时崩溃
iOS crash when I try to dismiss a modal
我使用模态转换动画对控制器进行模态化。但是当我试图关闭控制器时,程序崩溃了。 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];
}
问题可能在于在其他层之间移动层。您正在尝试插入已经在其他地方有超层的层。我不知道为什么它在呈现时还没有崩溃,但它在关闭时崩溃也就不足为奇了。
关闭视图控制器时,它们的状态不同。主要是,toView
已经是 containerView
的子视图。毕竟是 fromView
展示的时候。使用您的代码 view/layer 层次结构变得非常混乱,最终导致崩溃。
解决方法很简单。而不是创建单独的 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];
}
我使用模态转换动画对控制器进行模态化。但是当我试图关闭控制器时,程序崩溃了。 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];
}
问题可能在于在其他层之间移动层。您正在尝试插入已经在其他地方有超层的层。我不知道为什么它在呈现时还没有崩溃,但它在关闭时崩溃也就不足为奇了。
关闭视图控制器时,它们的状态不同。主要是,toView
已经是 containerView
的子视图。毕竟是 fromView
展示的时候。使用您的代码 view/layer 层次结构变得非常混乱,最终导致崩溃。
解决方法很简单。而不是创建单独的 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];
}