【发布时间】:2015-04-28 05:01:35
【问题描述】:
我是 Swift 新手,我正在尝试实现一个简单的游戏。在这个游戏中,一旦视图被加载,我希望周期性的动画发生。
问题是我尝试使用例如button.frame.origin.x += 50 为我的按钮设置动画,但不是将其从原点移动到右侧 50px,而是出现在 button.frame.origin.x - 50 并转到其(初始位置。
有趣的是,有一次我向用户显示了一个AlertDialog,在它显示之后,动画开始按我的预期发生。
我的问题与this topic 相同,但接受的答案并没有为我解决。
有什么想法吗?
编辑: 深入研究代码并进行大量测试,我发现显示 AlertDialog 的方法也恰好使我的计时器无效。我有两个计时器:一个用于更新 UI 时间(一个 TextField),另一个用于执行动画。两者都在安排任务。从I read here 来看,不可能有两个这样的计时器。
一个计时器对象一次只能在一个运行循环中注册, 虽然它可以添加到该运行中的多个运行循环模式 循环。
因此,显而易见的解决方案是将两个选择器(函数)合并为一个,以便计时器对这两个任务都有效。但是,如果我尝试更新 UI 并执行动画,动画将不再按预期工作。我只是迷失在这个问题上,无法让这两件事都发挥作用。
这些是我的重要代码:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
...
resetOrCreateGame()
}
func resetOrCreateGame() {
// Do stuff to initialize values
timerToRotate = NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: "rotateBlocks", userInfo: nil, repeats: true)
}
func rotateBlocks() {
// Calculate positions to rotate
UIView.animateWithDuration(0.5, delay: 0, options: UIViewAnimationOptions.CurveEaseOut, animations: {
// Try to update a timer in the UI
//self.timeLeft.text = String(self.seconds)
for i in 0 ... 8 {
println("\(i) before \(self.buttons[i].frame.origin.x) \(self.buttons[i].frame.origin.y)")
self.buttons[i].frame.origin.x = self.positions[self.indicesToRotate[i]].x
self.buttons[i].frame.origin.y = self.positions[self.indicesToRotate[i]].y
println("\(i) after \(self.buttons[i].frame.origin.x) \(self.buttons[i].frame.origin.y)")
}
}, completion: { _ in
println("completed")
})
如果我留下self.timeLeft.text = String(self.seconds) 的评论,动画效果很好。无论我如何尝试更新 timeLeft,如果我这样做,它会破坏我的动画。我试图在一个单独的线程中更新它,将它分派到主线程,甚至在动画闭包中更新它:它只是不起作用。
【问题讨论】:
-
您可以在您的应用程序中使用许多计时器。没事儿。您展示的描述谈到了一个计时器以及如何一次将其添加到一个运行循环中。
-
问题似乎是线程更新 UI,或类似的东西。即使只使用一个计时器,它仍然不起作用。请看我添加的代码