Как приостановить 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)
}
}
Несколько дополнительных наблюдений:
Если вы используете авто-макет, вы должны быть очень осторожны с настройкой
frame
из этих элементов управления. В автоматическом макете, если вам случится что-то сделать, чтобы запустить механизм ограничений (например, обновитьtext
из этих меток), элементы управления вернутся туда, где были определены ограничения.Вы меняете
frame
из этих элементов управления, перемещая их 2 балла за вызов. Это может привести к заиканию или изменению скорости анимационного интерфейса, поскольку ваше приложение становится более сложным. Не следует обновлять фиксированную сумму за вызов обработчика отображаемой ссылки, а использовать некоторые функции, основанные на времени, чтобы определить, сколько времени прошло, и рассчитать новые координаты по ним.Я лично не использовал бы ссылки показа для такого рода вещей. Я бы просто использовал стандарт
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
}