我是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,如果我这样做,它会搞砸我的动画。我试图在一个单独的线程中更新它,将它发送到主线程,或者甚至在动画闭包内更新它:它只是不起作用。
答案 0 :(得分:0)
尝试使用SKAction
来制作动画。
设置SKAction
,然后在要设置动画的SpriteKit node
上(用节点的名称替换" node
")并调用它action
。
然后,调用简单的方法:
[node runAction:action];
例如,如果您要设置SKAction
以在3秒的时间内向右移动标题为button
50像素的节点...
SKAction *action = [SKAction moveByX:50.0 y:0.0 duration:3.0];
[button runAction:action];
哎呀,如果我不经常做一次动作,我只是这样做:
[button runAction:[SKAction moveByX:50.0 y:0.0 duration:3.0]];
最后,您可以使用runAction:completion:
方法不仅可以运行SKAction
,还可以在完成后调用Objective-C block
,就像这样编码示例:
SKAction *action = [SKAction moveByX:50.0 y:0.0 duration:3.0];
[button runAction:action completion:^{
// some code here that runs after an animation completes
}];
并且,如果要在节点上运行序列操作(在3秒内将按钮向右移动一个名为button
的50个像素),则不要使代码复杂化淡出1秒以上),你可以将一系列动作编程为一个动作,如下所示:
SKAction *firstAction = [SKAction moveByX:50.0 y:0.0 duration:3.0];
SKAction *secondAction = [SKAction fadeAlphaTo:0.0 duration:1.0];
SKAction *theSequence = [SKAction sequence:[NSArray arrayWithObjects:firstAction, secondAction, nil];
[button runAction:theSequence]
您可以在completion
块中运行其他操作,但使用sequence
的方法可以清除代码。
答案 1 :(得分:0)
最后,我找到了解决方案! 出于某种原因的问题是自动布局。禁用后,一切按预期工作。
希望将来帮助某人!