2015-03-19 12 views
10

Sto provando a passare un UIButton con un userinfo di NSTimer. Ho letto ogni post su StackOverflow su NSTimers. Mi sto avvicinando molto ma non riesco a raggiungerlo. Questo post ha aiutatorapido NSTimer userinfo

Swift NSTimer retrieving userInfo as CGPoint

func timeToRun(ButonToEnable:UIButton) { 
    var tempButton = ButonToEnable 
    timer = NSTimer.scheduledTimerWithTimeInterval(4, target: self, selector: Selector("setRotateToFalse"), userInfo: ["theButton" :tempButton], repeats: false)  
} 

la funzione che il timer si

func setRotateToFalse() { 
    println( timer.userInfo)// just see whats happening 

    rotate = false 
    let userInfo = timer.userInfo as Dictionary<String, AnyObject> 
    var tempbutton:UIButton = (userInfo["theButton"] as UIButton) 
    tempbutton.enabled = true 
    timer.invalidate()  
} 

risposta

24

mi rendo conto che sei riuscito a risolvere questo problema, ma ho pensato di darvi qualche informazione in più su come utilizzare NSTimer. Il modo corretto per accedere all'oggetto timer e quindi alle informazioni utente è di utilizzarlo come di seguito. Quando l'inizializzazione il timer è possibile creare in questo modo:

Swift 2.x

NSTimer.scheduledTimerWithTimeInterval(4, target: self, selector: Selector("setRotateToFalse:"), userInfo: ["theButton" :tempButton], repeats: false) 

3.x Swift <

Timer.scheduledTimer(timeInterval: 1, target: self, selector:#selector(ViewController.setRotateToFalse), userInfo: ["theButton" :tempButton], repeats: false) 

Poi il callback si presenta così:

func setRotateToFalse(timer:NSTimer) { 
    rotate = false 
    let userInfo = timer.userInfo as Dictionary<String, AnyObject> 
    var tempbutton:UIButton = (userInfo["theButton"] as UIButton) 
    tempbutton.enabled = true 
    timer.invalidate()  
} 

Quindi non è necessario mantenere un riferimento al timer ed evitare variabili globali spesso spiacevoli dove possibile. Potresti incorrere in un problema in swift se la tua classe non eredita da NSObject dove dice che non è definito alcun callback ma che può essere facilmente risolto aggiungendo @objc all'inizio della definizione della funzione.

+0

Ciao, grazie che è molto utile – user2164327

+0

Nessun problema. Potresti segnare una risposta quando hai un momento. Cheers –

+1

Inoltre, non devi assolutamente passare un dizionario come 'userInfo', hai solo bisogno di un oggetto conforme a' AnyObject? '. Personalmente, l'ho usato per passare un 'String' – tfrank377

1

Stavo per pubblicare questo come ho letto su di esso prima ho postato. Ho notato che avevo timer.invalidate() prima di userinfo, ecco perché non funzionava. Lo posterò perché potrebbe aiutare qualcun altro.

func setRotateToFalse(timer:NSTimer) { 
    rotate = false 
    timer.invalidate() 
    let userInfo = timer.userInfo as Dictionary<String, AnyObject> 
    var tempbutton:UIButton = (userInfo["theButton"] as UIButton) 
    tempbutton.enabled = true 
} 
0

MacOS 10.12+ e iOS 10.0+ introduce un'API basata blocco di Timer che è un modo più conveniente

func timeToRun(buttonToEnable: UIButton) { 
    timer = Timer.scheduledTimer(withTimeInterval:4, repeats: false) { timer in 
     buttonToEnable.enabled = true 
    }  
} 

A un timer colpo decade automaticamente dopo che gli incendi.


Un modo conveniente simile per uno timer colpo sta usando GCD (DispatchQueue.main.asyncAfter)

func timeToRun(buttonToEnable: UIButton) { 
    DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(4)) { 
     buttonToEnable.enabled = true 
    } 
}