web-dev-qa-db-ja.com

swift NSTimer userinfo

NSTimerのuserinfoを使用してUIButtonを渡そうとしています。 NSTimersのstackoverflowに関するすべての投稿を読みました。近づいていますが、なかなか行けません。この投稿は役に立ちました

Swift NSTimerがuserInfoをCGPointとして取得

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

タイマーが実行する機能

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

あなたはこれをなんとか修正できたと思いますが、NSTimerの使用についてもう少し情報を提供したいと思いました。タイマーオブジェクト、つまりユーザー情報にアクセスする正しい方法は、以下のように使用することです。タイマーを初期化するときは、次のように作成できます。

スイフト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)

すると、コールバックは次のようになります。

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

したがって、タイマーへの参照を保持する必要はなく、可能な場合は厄介なグローバル変数を避ける必要があります。クラスがNSObjectから継承しない場合、Swiftで問題が発生する可能性があります。コールバックが定義されていないと表示されますが、これは@objcを追加することで簡単に修正できます。関数定義の始まり。

28

macOS10.12 +およびiOS10.0 +では、より便利な方法であるTimerのブロックベースのAPIが導入されています

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

ワンショットタイマーは、発火後に自動的に無効になります。


ワンショットタイマーの同様の便利な方法は、GCD(DispatchQueue.main.asyncAfter

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

投稿する前に読んだので、これを投稿するつもりでした。 userinfoの前にtimer.invalidate()があることに気づいたので、それが機能していませんでした。他の人の役に立つかもしれないので投稿します。

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
}
1
user2164327