Ios 卡巴斯基化有时有效,有时失败

Ios 卡巴斯基化有时有效,有时失败,ios,swift,core-animation,cabasicanimation,Ios,Swift,Core Animation,Cabasicanimation,我正在制作一个应用程序,通过一系列步骤引导用户创建帐户。完成每一步后,用户将被带到下一个视图控制器,屏幕顶部会出现一个进度条动画,以告知账户制作过程完成了多少。以下是最终结果: 这是通过在包含视图中放置导航控制器来实现的。进度条放置在包含的视图上,每次导航控制器推送新的视图控制器时,它都会告诉包含的视图控制器将进度条设置为superview宽度的某个百分比。这是通过以下updateProgressBar函数完成的 导入UIKit 类ContainerVC:UIViewController{ v

我正在制作一个应用程序,通过一系列步骤引导用户创建帐户。完成每一步后,用户将被带到下一个视图控制器,屏幕顶部会出现一个进度条动画,以告知账户制作过程完成了多少。以下是最终结果:

这是通过在包含视图中放置导航控制器来实现的。进度条放置在包含的视图上,每次导航控制器推送新的视图控制器时,它都会告诉包含的视图控制器将进度条设置为superview宽度的某个百分比。这是通过以下
updateProgressBar
函数完成的

导入UIKit
类ContainerVC:UIViewController{
var progressBar:现金支付者!
重写func viewdilayoutsubviews(){
super.viewDidLayoutSubviews()
progressBar=CAShapeLayer()
progressBar.bounds=CGRect(x:0,y:0,宽度:0,高度:view.safeAreaInsets.top)
progressBar.position=CGPoint(x:0,y:0)
progressBar.anchorPoint=CGPoint(x:0,y:0)
progressBar.backgroundColor=UIColor.secondaryColor.cgColor
view.layer.addSublayer(progressBar)
}
func updateProgressBar(到百分比asDecimal:CGFloat!){
设newWidth=view.bounds.width*percentAsDecimal
CATransaction.begin()
CATransaction.setCompletionBlock({
self.progressBar.bounds.size.width=newWidth
})
CATransaction.commit()
让anim=cabasicanitation(关键路径:“边界”)
anim.isRemovedOnCompletion=true
动画持续时间=0.25
anim.fromValue=NSValue(cgRect:cgRect(x:0,y:0,宽度:progressBar.bounds.width,height:view.safeAreaInsets.top))
anim.toValue=NSValue(cgRect:cgRect(x:0,y:0,width:newWidth,height:view.safeAreaInsets.top))
progressBar.add(动画,forKey:“动画”)
}
}
当按下下一个VC时,导航控制器堆栈中的视图控制器将调用此函数。这是这样做的:

class FourthViewController:UIViewController{
var containerVC:ContainerViewController!
...
@iAction func NextButton按下(u发送方:任何){
让故事板=UIStoryboard(名称:“Main”,捆绑包:.Main)
让fifthVC=storyboard.instanceeviewcontroller(标识符为“fifthVC”)作为!FifthViewController
fifthVC.containerVC=containerVC
navigationController!.pushViewController(第五个,动画:true)
//我们通过了5/11,因为下一步将是11个步骤中的第5步
self.containerVC.updateProgressBar(至:5/11)
}
}
类似地,当按下后退按钮时,我们收缩容器VC的进度条:

class FourthViewController:UIViewController{
var containerVC:ContainerViewController!
...
@iAction func backButtonPressed(u发送方:任意){
navigationController!.popViewController(动画:true)
//我们通过了3/11,因为上一步是11个步骤中的第3步
containerVC.updateProgressBar(截止日期:3/11)
}
}
我的问题是,这种动画有时只起作用。进度条在过程中向前移动时始终有效,但有时,当用户向后导航时,进度条会被卡住,在显示未访问的视图控制器之前,进度条不会再向任何方向移动。请看下面的视频:


我已经确认,警报控制器的显示不是动画制作失败的原因,并且已经确保动画在主线程上发生。有什么建议吗?

正如在这个答案中解释的那样,
viewdilayoutsubviews()
会被多次调用

在您的情况下,每次从导航堆栈中推送或弹出视图控制器时,都会安装一个新的
CAShapeLayer


试着改用
viewdideappease()

我很惊讶自己竟然傻到看不到这一点