ios - CABasicAnimation 有时有效,有时失败
<p><p>我正在制作一个应用程序,通过一系列步骤引导用户创建帐户。完成每个步骤后,用户将被带到下一个 ViewController ,并且屏幕顶部会出现一个进度条动画,以传达已完成的帐户创建过程的多少。这是最终结果:</p>
<p> <a href="/image/Uwfqw.gif" rel="noreferrer noopener nofollow"><img src="/image/Uwfqw.gif" alt="enter image description here"/></a> </p>
<p>这是通过在包含 View 中放置导航 Controller 来实现的。进度条覆盖在包含 View 上,每次导航 Controller 推送一个新的 ViewController 时,它都会告诉包含 ViewController 将进度条设置为父 View 宽度的某个百分比。这是通过以下 <code>updateProgressBar</code> 函数完成的。</p>
<pre class="lang-swift prettyprint-override"><code>import UIKit
class ContainerVC: UIViewController {
var progressBar: CAShapeLayer!
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
progressBar = CAShapeLayer()
progressBar.bounds = CGRect(x: 0, y: 0, width: 0, height: 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(to percentAsDecimal: CGFloat!) {
let newWidth = view.bounds.width * percentAsDecimal
CATransaction.begin()
CATransaction.setCompletionBlock({
self.progressBar.bounds.size.width = newWidth
})
CATransaction.commit()
let anim = CABasicAnimation(keyPath: "bounds")
anim.isRemovedOnCompletion = true
anim.duration = 0.25
anim.fromValue = NSValue(cgRect: CGRect(x: 0, y: 0, width: progressBar.bounds.width, height: view.safeAreaInsets.top))
anim.toValue = NSValue(cgRect: CGRect(x: 0, y: 0, width: newWidth, height: view.safeAreaInsets.top))
progressBar.add(anim, forKey: "anim")
}
}
</code></pre>
<p>导航 Controller 堆栈中的 ViewController 将在推送下一个 VC 时调用此 <code>updateProgressBar</code> 函数。这样做是这样的:</p>
<pre class="lang-swift prettyprint-override"><code>class FourthViewController: UIViewController {
var containerVC: ContainerViewController!
...
@IBAction func nextButtonPressed(_ sender: Any) {
let storyboard = UIStoryboard(name: "Main", bundle: .main)
let fifthVC = storyboard.instantiateViewController(withIdentifier: "FifthVC") as! FifthViewController
fifthVC.containerVC = containerVC
navigationController!.pushViewController(fifthVC, animated: true)
//We pass 5/11 because the next step will be step 5 out of 11 total steps
self.containerVC.updateProgressBar(to: 5/11)
}
}
</code></pre>
<p>同理,当按下返回键时,我们收缩容器VC的进度条:</p>
<pre class="lang-swift prettyprint-override"><code>class FourthViewController: UIViewController {
var containerVC: ContainerViewController!
...
@IBAction func backButtonPressed(_ sender: Any) {
navigationController!.popViewController(animated: true)
//We pass 3/11 because the previous step is step 3 out of 11 total steps
containerVC.updateProgressBar(to: 3/11)
}
}
</code></pre>
<p>我的问题是这个动画有时只能工作。进度条在进程中向前移动时始终有效,但有时,当用户向后导航时,进度条会卡住并且不会再向任一方向移动,直到出现未到达的 ViewController 。请看下面的视频:</p>
<p> <a href="https://www.youtube.com/watch?v=63_QFp9Jj1c&feature=youtu.be" rel="noreferrer noopener nofollow">Video of Bug (Bug begins around 0:23)</a> </p>
<p>我已确认警报 Controller 的显示不是动画失败的原因,并且还确保动画正在主线程上发生。有什么建议吗?</p></p>
<br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
<p><p>正如这个答案中很好解释的 <a href="https://stackoverflow.com/questions/40737164/whats-exactly-viewdidlayoutsubviews" rel="noreferrer noopener nofollow">here</a> , <code>viewDidLayoutSubviews()</code> 被多次调用。</p>
<p>在您的情况下,每次您从导航堆栈中推送或弹出 ViewController 时,您最终都会实例化一个新的 <code>CAShapeLayer</code>。</p>
<p>尝试改用 <code>viewDidAppear()</code>。</p></p>
<p style="font-size: 20px;">关于ios - CABasicAnimation 有时有效,有时失败,我们在Stack Overflow上找到一个类似的问题:
<a href="https://stackoverflow.com/questions/57777822/" rel="noreferrer noopener nofollow" style="color: red;">
https://stackoverflow.com/questions/57777822/
</a>
</p>
页:
[1]