【问题标题】:UIView.animateWithDuration completes too early when changing view with Tab Bar Controller使用标签栏控制器更改视图时,UIView.animateWithDuration 过早完成
【发布时间】:2015-10-19 08:50:54
【问题描述】:

我正在通过增加简单图像的 with 来制作进度条:

let progressBar = createProgressBar(width: self.view.frame.width, height: 60.0)
let progressBarView = UIImageView(image: progressBar)
progressBarView.frame = CGRect(x: 0, y: 140, width: 0, height: 60)
UIView.animateWithDuration(60.0, delay: 0.0, options: [], animations: {
    progressBarView.frame.size.width = self.backgroundView.frame.size.width
    }, completion: {_ in
        print("progress completed")
    }
)

这按预期工作,但在使用 TabBarController 更改视图时遇到问题。当我改变视图时,我希望进度条在后台继续动画,这样我就可以回到这个视图来检查进度,但是当我改变视图时它会立即结束,并调用完成块。

为什么会发生这种情况,如何解决?

【问题讨论】:

  • “改变视图”是什么意思?是不是又选择了TabBarController的另一个childViewController?
  • 是的,只需点击其中一个标签栏项目即可切换到另一个视图控制器。

标签: ios swift uiview animatewithduration


【解决方案1】:

当您点击另一个 tabBar 项目时,正在执行动画的viewController 将处于viewDidDisappear 的状态,并且动画将被移除。

其实不建议在viewController没有呈现在屏幕前面的时候执行任何动画。

要继续中断的动画进度,您必须保持动画的当前状态并在 tabBar 项目切换回来时恢复它们。

例如,您可以持有一些实例变量来保持动画的持续时间、进度、开始宽度和结束宽度。并且可以在viewDidAppear中恢复动画:

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    // `self.duration` is the total duration of the animation. In your case, it's 60s.
    // `self.progress` is the time that had been consumed. Its initial value is 0s.
    // `self.beginWidth` is the inital width of self.progressBarView.
    // `self.endWidth`, in your case, is `self.backgroundView.frame.size.width`.

    if self.progress < self.duration {

        UIView.animateWithDuration(self.duration - self.progress, delay: 0, options: [.CurveLinear], animations: {

            self.progressBarView.frame.size.width = CGFloat(self.endWidth)
            self.beginTime = NSDate() // `self.beginTime` is used to track the actual animation duration before it interrupted.

            }, completion: { finished in
                if (!finished) {
                    let now = NSDate()
                    self.progress += now.timeIntervalSinceDate(self.beginTime!)
                    self.progressBarView.frame.size.width = CGFloat(self.beginWidth + self.progress/self.duration * (self.endWidth - self.beginWidth))
                } else {
                    print("progress completed")
                }
            }
        )
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-13
    • 2016-12-17
    • 1970-01-01
    • 2017-08-23
    相关资源
    最近更新 更多