【问题标题】:How do I animate the width of a UIView with a Timer?如何使用 Timer 为 UIView 的宽度设置动画?
【发布时间】:2017-04-18 21:05:24
【问题描述】:

我有一个设置为我的视图宽度的视图和一个在未来(在接下来的 5 分钟内)获取某个时间点的计时器。我的目标是将视图的宽度从view.width 降至 0

我正在尝试做

UIView.animate(withDuration: date.timeIntervalSinceNow, delay: 0, options: .curveEaseIn, animations: {
    self.countdownBar?.frame = CGRect(x: 0, y:self.view.frame.maxY - 3, width: 0, height: 3)
}, completion: nil)

但这使得 countdownBar 动画从视图顶部向下移动到 maxY 位置 - 3 而不是宽度

任何帮助将不胜感激!

编辑:计时器代码

self.timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.countdownToCartExpiration), userInfo: nil, repeats: true)

countdownToCartExpiration 中,我会以特定的时间间隔(分钟和秒)进行一些 UI 更改

【问题讨论】:

    标签: swift uiview uiviewanimation animatewithduration


    【解决方案1】:

    您应该使用计时器之类的东西,或者只使用 UIViewAnimation。

    如果您想在 5 分钟内将 width 动画化为 0,那么您可以这样做。

    var finalFrame = countdownBar!.frame
    finalFrame.size.width = 0
    
    UIView.animate(withDuration: 300, animations: {
        self.countdownBar?.frame = finalFrame
    })
    

    这假定视图是屏幕的整个宽度,并将在 300 秒内将其动画化为零。它还假设您没有使用 AutoLayout 来管理您的布局。如果您使用的是 Autolayout,那么我们需要调整它以更改约束而不是更改框架。

    更新

    因此,既然您有一个每秒触发一次的计时器。我们仍然可能希望制作动画。如果计时器每 30 秒或 60 秒触发一次,那么我们可以调整帧,它看起来会很平滑。但每一秒都会显得波涛汹涌。

    func countdownToCartExpiration (timer: Timer) {
    
        guard let countdownBar = countdownBar else {
            return
        }
    
        // Assuming you're already tracking currentTime somehow
        currentTime += timer.timeInterval
    
        var finalFrame = countdownBar.frame
        let totalTime = 300.0
    
        finalFrame.size.width = view.frame.width * CGFloat(currentTime / totalTime)
    
        UIView.animate(withDuration: timer.timeInterval, delay: 0, options: [.beginFromCurrentState, .curveLinear], animations: {
            countdownBar.frame = finalFrame
        }, completion: nil)
    
        // ... Other stuff
    }
    

    . beginFromCurrentState 很重要,以防动画发生重叠。 .curveLinear 在这里很重要,因为我们希望动画速度保持不变。

    我假设您正在跟踪 currentTime 并且此动画的总时间为 300 秒。但是你可以明显地调整。目标是将宽度设置为 currentTime 占 totalTime 的百分比。

    【讨论】:

    • 我已经有一个定时器了,我宁愿使用而不是 animate
    • 顺便说一句,finalFrame.width = 0 抛出错误“width is a get-only property”
    • 哎呀,你需要finalFrame.size.width。我已经更新了它。至于计时器,您可以发布您设置的计时器和您正在调用的方法吗?如果您想使用计时器手动更改宽度,那么我们需要在计时器期间定期调用一个方法。这是进度条之类的东西吗?
    • 我让它工作了,我最终使用了 NSLayoutConstraint,将常量设置为 -countdownBar.width 并制作动画。再次感谢您的帮助瑞恩,我很感激
    • 是的,如果您使用 AutoLayout,则无法触摸框架;)
    猜你喜欢
    • 2012-10-02
    • 2017-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-23
    • 1970-01-01
    • 1970-01-01
    • 2014-06-27
    相关资源
    最近更新 更多