[英]How to pause a 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.
}
謝謝。 安東
您需要存儲對在按鈕單擊處理程序中創建的顯示鏈接的引用。 因此,為它們創建類級別的屬性:
@IBAction func button5(sender: UIButton) {
button4.hidden = true
label2.hidden = false
}
// new code here:
var displayLink: CADisplayLink?
var displayLink1: CADisplayLink?
如果實例已經存在,則在創建它們之前使它們無效:
@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
}
這非常令人困惑,因為尚不清楚兩個出口(稱為button2
和button4
與@IBAction
方法(稱為button1
, button3
和button5
? 您實際上有幾個按鈕? 二? 四? 五? 這些不同的標簽是什么? 如果它們不是問題的一部分,則不應將其包含在代碼段中。
但是,如果要調用的是button3
或button5
,則是的,它們會隱藏該按鈕,但不會invalidate
顯示鏈接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
應該使用這些屬性,而不是對displayLink
和displayLink1
使用局部變量:
@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)
}
}
其他一些觀察:
如果您使用的是自動版式,則應謹慎調整這些控件的frame
。 在自動布局中,如果您碰巧執行任何操作來觸發要應用的約束引擎(例如,更新這些標簽的text
),則控件將移回到約束將其定義為的位置。
您正在更改這些控件的frame
,每次調用將它們移動2點。 隨着您的應用程序變得越來越復雜,最終可能會導致動畫UI的停頓或速度改變。 您不應該為每次調用顯示鏈接處理程序更新固定的金額,而應使用一些基於時間的函數來確定已花費了多少時間並從中計算出新的坐標。
我個人不會將顯示鏈接用於此類內容。 我只使用標准的UIView.animateWithDuration
,然后當我想停止button2移動時,我會:
let currentButton2Frame = button2.layer.presentationLayer()!.frame button2.layer.removeAllAnimations() button2.frame = currentButton2Frame
這會在動畫中期確定它在哪里,停止動畫,並將frame
重置為先前確定的坐標。 這避免了顯示鏈接的復雜性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.