如何暂停一个CADisplayLink?

我在我的应用程序中遇到问题。 我想要发生的是当我点击button2时,它消失并停止移动。 现在发生的事情是,当我点击button2时,它会消失,但不会停止移动(即使它隐藏)。任何帮助? 码:

@IBOutlet var label: UILabel! @IBOutlet var label2: UILabel! @IBOutlet var label3: UILabel! @IBOutlet var button2: UIButton! @IBAction func button3(sender: UIButton) { label.hidden = false button2.hidden = true } @IBOutlet var button4: UIButton! @IBAction func button5(sender: UIButton) { button4.hidden = true label2.hidden = false } @IBAction func button1(sender: UIButton) { label.hidden = true label2.hidden = true button2.hidden = false button2.frame = CGRectMake(120, 400, 100, 100) let displayLink = CADisplayLink(target: self, selector: "handleDisplayLink:") displayLink.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode) let time = dispatch_time(dispatch_time_t(DISPATCH_TIME_NOW), 2 * Int64(NSEC_PER_SEC)) dispatch_after(time, dispatch_get_main_queue()) { self.button4.hidden = false self.button4.frame = CGRectMake(120, 400, 100, 100) let displayLink1 = CADisplayLink(target: self, selector: "handleDisplayLink1:") displayLink1.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)} } func handleDisplayLink(displayLink: CADisplayLink) { var buttonFrame = button2.frame buttonFrame.origin.y += -2 button2.frame = buttonFrame if button2.frame.origin.y <= 50 { displayLink.invalidate() label3.hidden = false button2.hidden = true } } func handleDisplayLink1(displayLink1: CADisplayLink) { var button4Frame = button4.frame button4Frame.origin.y += -2 button4.frame = button4Frame if button4.frame.origin.y <= 50 { displayLink1.invalidate() label3.hidden = false button4.hidden = true } } override func viewDidLoad() { super.viewDidLoad() label.hidden = true button2.hidden = true label2.hidden = true button4.hidden = true label3.hidden = true // Do any additional setup after loading the view, typically from a nib. } 

谢谢。 安东

这是非常令人困惑的,因为不清楚称为button2button4的两个sockets与称为button1button3button5@IBAction方法之间的关系。 你有多less个button? 二? 四? 五? 而这些各种标签呢? 如果他们不是问题的一部分,他们不应该包含在代码片段中。

但是,如果是button3button5被调用,那么是的,这些隐藏button,但不显示链接invalidate ,所以显示链接将进展。 如果你想要停止显示链接,那么你必须调用invalidate

 var displayLink: CADisplayLink? var displayLink1: CADisplayLink? @IBAction func button3(sender: UIButton) { label.hidden = false button2.hidden = true displayLink?.invalidate() displayLink = nil } @IBAction func button5(sender: UIButton) { button4.hidden = true label2.hidden = false displayLink1?.invalidate() displayLink1 = nil } 

这显然意味着button5应该使用这些属性,而不是使用displayLinkdisplayLink1局部variables:

 @IBAction func button1(sender: UIButton) { label.hidden = true label2.hidden = true button2.hidden = false button2.frame = CGRectMake(120, 400, 100, 100) // NB: No `let` on the next line displayLink = CADisplayLink(target: self, selector: "handleDisplayLink:") displayLink?.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode) let time = dispatch_time(dispatch_time_t(DISPATCH_TIME_NOW), 2 * Int64(NSEC_PER_SEC)) dispatch_after(time, dispatch_get_main_queue()) { self.button4.hidden = false self.button4.frame = CGRectMake(120, 400, 100, 100) // NB: No `let` on the next line self.displayLink1 = CADisplayLink(target: self, selector: "handleDisplayLink1:") self.displayLink1?.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode) } } 

还有一些意见:

  1. 如果你正在使用自动布局,你应该非常谨慎的调整这些控件的frame 。 在自动布局中,如果您碰巧做了任何事情来触发应用约束引擎(例如更新这些标签的text ),则控件将回到约束定义的位置。

  2. 你正在改变这些控件的frame ,每次调用2点。 随着应用程序变得越来越复杂,这可能最终会导致animationUI的速度变慢或变化。 您不应每次更新显示链接处理程序的固定数量,而是使用一些基于时间的函数来确定已经过多less时间,并从中计算新的坐标。

  3. 我个人不会使用这种东西的显示链接。 我只是使用标准的UIView.animateWithDuration ,然后当我想停止button2移动时,我会:

     let currentButton2Frame = button2.layer.presentationLayer()!.frame button2.layer.removeAllAnimations() button2.frame = currentButton2Frame 

    这确定了它在哪里,在animation中,停止animation,并将frame重置到先前识别的坐标。 这避免了显示链接的复杂性。

您需要存储对您在button点击处理程序中创build的显示链接的引用。 所以为它们创build类级别的属性:

 @IBAction func button5(sender: UIButton) { button4.hidden = true label2.hidden = false } // new code here: var displayLink: CADisplayLink? var displayLink1: CADisplayLink? 

然后在创build它们之前使它们无效,以防一个实例已经存在:

 @IBAction func button1(sender: UIButton) { displayLink?.invalidate() displayLink1?.invalidate() displayLink = CADisplayLink(target: self, selector: "handleDisplayLink:") displayLink1 = CADisplayLink(target: self, selector: "handleDisplayLink1:") displayLink = label.hidden = true label2.hidden = true button2.hidden = false // ... rest of your method }