我有一个按钮(实际上是两个几乎相同的按钮),在另一个UIView中取消隐藏动作。
第二个UIView在第二个UIView结束后使用dispatch_after结束后2秒钟自动隐藏按钮,但是如果按钮在可见时被点击,我想保持按钮可见。这是timer属性和UIButton子类中的两个方法。我有一个@IBAction调用" justTapped"在ViewController中。
var timer = NSTimer()
func hideAndShrink(){
if !self.hidden && !timer.valid{
self.hidden = true
}
}
func justTapped(){
timer.invalidate()
timer = NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: "hideAndShrink", userInfo: nil, repeats: false)
}
点击任一按钮后,它们都不会隐藏。
在调用选择器中的方法时,计时器是否仍然有效?
得益于luk2302,答案是肯定的,定时器在发送选择器时有效
我怎样才能解决这个问题?
正如所建议的那样,我为计时器编写了第二种方法,它隐藏了没有!timer.valid的按钮?
事实证明我根本不需要第二种方法,因为我只是试图隐藏调用justTapped的按钮。这是两个按钮的扩展和缩小动画的最终代码。 self.direction是我希望按钮从下到上或从上到下展开的方向,并且还决定了背景图像。我认为这可能是一个列举,但我还没有想出那些。
func unhideAndExpand(){
if self.hidden{
expand(self.frame.size.height)
}
}
func hideAndShrink(){
if !self.hidden && !shrinking{
shrink(self.frame.size.height)
}
}
func justTapped(){
timer.invalidate()
timer = NSTimer.scheduledTimerWithTimeInterval(3.0, target: self, selector: "hideAndShrink", userInfo: nil, repeats: false)
}
func expand(height: CGFloat){
if self.direction == "up"{
self.transform = CGAffineTransformMake(1, 0, 0, 1/height, 1, height/2)
} else if self.direction == "down" {
self.transform = CGAffineTransformMake(1, 0, 0, 1/height, 1, -height/2)
}
self.hidden = false
UIView.animateWithDuration(0.5, delay: 0, options: .CurveEaseOut, animations:
{self.transform = CGAffineTransformIdentity}, completion: nil)
}
func shrink(height: CGFloat){
self.shrinking = true
UIView.animateWithDuration(0.5, delay: 0, options: .CurveEaseOut, animations:
{if self.direction == "up"{
self.transform = CGAffineTransformMake(1, 0, 0, 1/height, 1, height/2)
} else if self.direction == "down" {
self.transform = CGAffineTransformMake(1, 0, 0, 1/height, 1, -height/2)
}
}, completion: {_ in
self.transform = CGAffineTransformIdentity
self.hidden = true
self.shrinking = false})
}
感谢大家的帮助。
答案 0 :(得分:0)
您确定需要!timer.valid
检查吗?如果hideAndShrink
仅由计时器调用,则您似乎可以将其更改为
func hideAndShrink(){
self.hidden = true
}
只有在计时器未失效时才会调用 hideAndShrink
,因此您可以跳过此检查。
答案 1 :(得分:0)
在调用选择器中的方法时,计时器是否仍然有效?
以下是一个完整的可运行游乐场示例,展示了:
import Foundation
import XCPlayground
XCPSetExecutionShouldContinueIndefinitely()
class Bla {
var timer : NSTimer?
init() {
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "check", userInfo: nil, repeats: false)
NSTimer.scheduledTimerWithTimeInterval(1.1, target: self, selector: "checkAgain", userInfo: nil, repeats: false)
}
@objc func check(){
print(timer!.valid)
}
@objc func checkAgain(){
check()
}
}
let bla = Bla()
这将首先输出true
,然后输出false
。 触发时,计时器仍然有效。一旦你离开被解雇的方法,计时器就会失效。
这将使您的if
无效,因为该方法在计时器触发时无效,因为anything && !true
评估为false
。
如何绕过该问题,可以创建一种不同的方法timerFired
,它可以设置您班级的某些内部属性,例如var timerHasFired = false
到true
。你的``那么必须检查那个变量而不是计时器:
var timer = NSTimer()
var timerHasFired = false
func hideAndShrink(){
if !self.hidden && hideAndShrink {
self.hidden = true
}
}
func timerFired() {
timerHasFired = true
hideAndShrink()
}
func justTapped(){
timer.invalidate()
timer = NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: "timerFired", userInfo: nil, repeats: false)
}