Как приостановить CADisplayLink?

У меня есть проблема в моем приложении. То, что я хочу, чтобы произошло, когда я нажимаю кнопку2, он исчезает и перестает двигаться. Что происходит сейчас, так это то, что когда я нажимаю кнопку 2, она исчезает, но не перестает двигаться (даже когда скрыта). Любая помощь? Код:

@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.  
}

Спасибо. Антон

2 ответа

Решение

Это очень запутанно, потому что неясно, как соотносятся button2 а также button4 и @IBAction методы называются button1, button3, а также button5? Сколько кнопок на самом деле у вас есть? Два? Четыре? 5? А что это за различные ярлыки? Если они не являются частью вопроса, их не следует включать в фрагмент кода.

Но если это button3 или же button5 это называется, тогда да, те скрывают кнопку, но не 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)
    }
}

Несколько дополнительных наблюдений:

  1. Если вы используете авто-макет, вы должны быть очень осторожны с настройкой frame из этих элементов управления. В автоматическом макете, если вам случится что-то сделать, чтобы запустить механизм ограничений (например, обновить text из этих меток), элементы управления вернутся туда, где были определены ограничения.

  2. Вы меняете frame из этих элементов управления, перемещая их 2 балла за вызов. Это может привести к заиканию или изменению скорости анимационного интерфейса, поскольку ваше приложение становится более сложным. Не следует обновлять фиксированную сумму за вызов обработчика отображаемой ссылки, а использовать некоторые функции, основанные на времени, чтобы определить, сколько времени прошло, и рассчитать новые координаты по ним.

  3. Я лично не использовал бы ссылки показа для такого рода вещей. Я бы просто использовал стандарт UIView.animateWithDurationи затем, когда я хотел остановить перемещение button2, я бы:

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

    Он определяет, где он находится, в середине анимации, останавливает анимацию и сбрасывает frame с координатами, ранее определенными. Это позволяет избежать сложностей отображения ссылок.

Вам нужно сохранить ссылку на отображаемые ссылки, которые вы создаете, в вашем обработчике нажатий кнопок. Поэтому создайте для них свойства уровня класса:

@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
}
Другие вопросы по тегам