更新屏幕外的 UILabels 导致它们 "Snap" 返回

Updating UILabels Off-Screen Causing Them To "Snap" Back

背景信息

我正在构建一个微型秒表应用程序。它由一个带有显示时间标签的主视图和两个按钮组成:开始和停止。
开始按钮激活 NSTimers,然后调用计算经过时间的方法,然后相应地更新标签。停止按钮只是使计时器无效。

在右上角,有一个箭头按钮,可以将所有 UI 元素向左移动并显示菜单。当计时器而不是 运行 并且标签没有被更新时,这很有效。

问题

但是,当 运行 计时器并因此同时更新标签时,在开始动画后不久,所有内容都会快速恢复到之前的位置。使用停止按钮使计时器无效时,动画再次正常工作。

演示

代码

动画 toggleMenu()

UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0.5, options: .CurveEaseOut, animations: {
    if self.arrow.frame.origin.x >= screenBounds.width/2 {
        //if menu is NOT visible (mainView ON-SCREEN, menu right)
        for element in self.UIElements {element.frame.origin.x -= screenBounds.width}
        self.arrow.frame.origin.x = 0
        self.arrow.transform = CGAffineTransformMakeRotation(CGFloat(-M_PI))
    } else {
        //if menu IS visible (mainView left, menu ON-SCREEN)
        for element in self.UIElements {element.frame.origin.x += screenBounds.width}
        self.arrow.frame.origin.x = screenBounds.width-self.arrow.frame.width
        self.arrow.transform = CGAffineTransformMakeRotation(CGFloat(0))
    }
    }, completion: nil)

正在调用定时器 updateTime()

更新标签
let currentTime = NSDate.timeIntervalSinceReferenceDate()
var elapsedTime: NSTimeInterval = currentTime - startTime

let hrs = UInt8(elapsedTime/3600)
elapsedTime -= NSTimeInterval(hrs)*3600
let mins = UInt8(elapsedTime/60)
elapsedTime -= NSTimeInterval(mins)*60
let secs = UInt8(elapsedTime)
elapsedTime -= NSTimeInterval(secs)

let strHrs  = String(format: "%02d", hrs)
let strMins = String(format: "%02d", mins)
let strSecs = String(format: "%02d", secs)

//update time labels
self.time.text = "\(strHrs):\(strMins)"
self.secs.text = "\(strSecs)"

尝试次数

没有运气,我试过了...

备注

我想...


有什么想法吗?
提前致谢!

当您更新标签时,Auto Layout 是 运行 并且将您的 UI 元素放回它们的约束规定的位置。您不应更改受 Auto Layout 控制的对象的框架,否则您会得到意想不到的结果。

不是更新 UI 元素的 origin.x,而是创建 @IBOutlet 到水平放置它们的 NSLayoutContraints,然后更新 constant 属性 的约束并在动画循环中调用 self.view.layoutIfNeeded()

让所有 UI 元素成为顶级 UIView 的子视图可能更容易,然后您只需要更新放置 UI 的一个约束=25=]水平查看以将其移出屏幕。