2015-03-19 17 views
10

Próbuję przekazać UIButton za pomocą informacji o użytkowniku NSTimer. Czytałem każdy post na stackoverflow na NSTimers. Zbliżam się bardzo, ale nie mogę się tam dostać. Ten post pomógłSwift 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)  
} 

funkcja timer biegnie

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()  
} 

Odpowiedz

24

ja sobie sprawę, że udało się to naprawić, ale myślałem, że chciałbym dać trochę więcej informacji na temat korzystania NSTimer. Prawidłowym sposobem uzyskania dostępu do obiektu timera, a tym samym informacji o użytkowniku, jest użycie go jak poniżej. Podczas inicjalizacji timera można utworzyć ją tak:

Swift 2.x

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

Swift 3.x <

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

Następnie zwrotna wygląda następująco:

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()  
} 

Dlatego nie trzeba utrzymywać odniesienia do licznika czasu i unikać często nieprzyjemnych zmiennych globalnych, gdy możliwy. Możesz szybko napotkać problem, jeśli twoja klasa nie dziedziczy po NSObject, gdzie mówi, że nie zdefiniowano żadnego wywołania zwrotnego, ale można to łatwo naprawić, dodając @objc na początku definicji funkcji.

+0

Hi dzięki, który jest bardzo pomocny – user2164327

+0

Nie ma problemu. Czy możesz oznaczyć odpowiedź, gdy masz chwilę. Pozdrawiam –

+1

Dodatkowo, nie musisz koniecznie przekazywać słownika jako 'userInfo', potrzebujesz tylko obiektu zgodnego z' AnyObject? '. Osobiście użyłem go do przekazania 'String' – tfrank377

1

właśnie zamiar pisać to jak czytam nad nim zanim napisałem. Zauważyłem, że przed informacją o użytkowniku miałem timer.invalidate(), dlatego nie działało. Opublikuję to, ponieważ może pomóc komuś innemu.

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+ i iOS 10.0+ wprowadza API opartego blokowy Timer który jest bardziej wygodny sposób

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

Jeden strzał czasomierz zostanie unieważnione automatycznie po pożary.


podobny wygodny sposób na jeden strzał czasomierz używa GCD (DispatchQueue.main.asyncAfter)

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