屏幕外更新UILabel会导致他们忘记" Snap"背部

时间:2016-07-06 16:27:50

标签: ios swift animation uilabel updating

背景资料

我正在构建一个小秒表应用程序。它包括一个主视图,带有显示时间的标签和两个按钮:start&停止。
启动按钮激活NSTimers,然后调用计算时间的方法,然后相应地更新标签。停止按钮只会使计时器无效。

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

问题

然而,当运行计时器时从而在开始动画后不久,同时更新标签,一切都快速回到之前的位置。使用停止按钮使计时器无效时,动画再次正常工作。

演示

Demo of the issue

代码

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)"

尝试

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

  • ...动画完成后隐藏标签
  • ...动画/隐藏所有元素'完成动画后的超级视图(clipsToBounds设置为真)

注意

我想......

  • ...评论标签正在更新的行"修复"问题
  • ...动画UI元素只移动几个像素(如100px)会导致同样的问题,这意味着问题发生在屏幕上和屏幕外


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

1 个答案:

答案 0 :(得分:1)

更新标签时,自动布局正在运行,并将UI元素放回到其约束条件应该存在的位置。您不应该更改受自动布局控制的对象的帧,否则您将获得意外的结果。

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

将所有UI元素设置为顶级UIView的子视图可能更容易,然后您只需更新一个将UIView水平放置在屏幕外的约束。