如何暂停 CADisplayLink? [英] How to pause a CADisplayLink?
问题描述
我的应用程序有问题.我想要发生的是当我单击 button2 时,它消失并停止移动.现在发生的事情是,当我单击 button2 时,它会消失但不会停止移动(即使它处于隐藏状态).有帮助吗?代码:
I have a problem in my app. What I want to happened is when I click button2, it disappears and stops moving. What's happening now is that when I click button2, it disappears but doesn't stop moving (even while its hidden).Any help? Code:
@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.
}
谢谢.安东
推荐答案
这非常令人困惑,因为不清楚 button2
和 button4
两个出口之间的关系以及名为 button1
、button3
和 button5
的 @IBAction
方法?你实际上有多少个按钮?二?四?五?这些不同的标签是什么?如果它们不是问题的一部分,则不应将它们包含在代码段中.
This is exceedingly confusing because it's unclear as to the relationship between the two outlets called button2
and button4
and the @IBAction
methods called button1
, button3
, and button5
? How many buttons do you actually have? Two? Four? Five? And what these various labels? If they're not part of the question, they shouldn't be included in the code snippet.
但是如果 button3
或 button5
被调用,那么是的,它们隐藏了按钮,但不会 invalidate
显示链接,因此显示链接将继续进行.如果你想让它停止显示链接,那么你必须调用invalidate
:
But if it's button3
or button5
that's getting called, then yes, those hide the button, but don't invalidate
the display link, so the display link will progress. If you want it to stop the display link, then you have to call 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
使用局部变量:
This obviously means that button5
should be using these properties, not using local variables for displayLink
and 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
),控件将移回约束定义它们所在的位置.
If you're using auto-layout, you should be very wary about just adjusting the
frame
of these controls. In auto-layout, if you happen to do anything to trigger the constraints engine to be applied (e.g. update thetext
of these labels), the controls will move back to where the constraints defined them to be.
您正在更改这些控件的 frame
,每次调用将它们移动 2 个点.随着您的应用程序变得越来越复杂,这可能最终导致动画 UI 的卡顿或速度变化.您不应在每次调用显示链接处理程序时更新固定数量,而应使用一些基于时间的函数来确定已经过去了多少时间并从中计算新坐标.
You're changing the frame
of these controls, moving them 2 points per call. That's might end up with stuttering or changing of speeds of the animation UI as your app gets more complicated. You shouldn't update a fixed amount per call of the display link handler, but rather use some time based functions to determine how much time has elapsed and calculate the new coordinates from that.
我个人不会将显示链接用于此类内容.我只会使用标准的 UIView.animateWithDuration
,然后当我想阻止 button2 移动时,我会:
I personally wouldn't use display links for this kind of stuff. I would just use the standard UIView.animateWithDuration
, and then when I wanted to stop button2 from moving, I would:
let currentButton2Frame = button2.layer.presentationLayer()!.frame
button2.layer.removeAllAnimations()
button2.frame = currentButton2Frame
这标识了它的位置,中间动画,停止动画,并将 frame
重置为先前标识的坐标.这避免了显示链接的复杂性.
This identifies where it is, mid-animation, stops the animation, and resets the frame
to the coordinates previously identified. This avoids the complexities of display links.
这篇关于如何暂停 CADisplayLink?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!