我正在构建一个小秒表应用程序。它包括一个主视图,带有显示时间的标签和两个按钮:start&停止。
启动按钮激活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)"
没有运气,我试过......
clipsToBounds
设置为真)我想......
有什么想法吗?
提前谢谢!
答案 0 :(得分:1)
更新标签时,自动布局正在运行,并将UI元素放回到其约束条件应该存在的位置。您不应该更改受自动布局控制的对象的帧,否则您将获得意外的结果。
不是更新UI元素的origin.x
,而是创建@IBOutlet
到水平放置它们的NSLayoutContraints
,然后更新约束的constant
属性并调用动画循环中的self.view.layoutIfNeeded()
。
将所有UI元素设置为顶级UIView的子视图可能更容易,然后您只需更新一个将UIView水平放置在屏幕外的约束。