Swift에서 타이머 (이전의 NSTimer)를 사용하려면 어떻게해야합니까?


257

나는 시도했다

var timer = NSTimer()
timer(timeInterval: 0.01, target: self, selector: update, userInfo: nil, repeats: false)

그러나 오류가 발생했습니다.

'(timeInterval: $T1, target: ViewController, selector: () -> (), userInfo: NilType, repeats: Bool) -> $T6' is not identical to 'NSTimer'

1
"Swift에서 NSTimer를 어떻게 사용할 수 있습니까?" – Objective-C에서 사용하는 것과 같은 방식입니다. API는 변경되지 않았습니다.
상자성 크로와상

답변:


534

이것은 작동합니다 :

override func viewDidLoad() {
    super.viewDidLoad()
    // Swift block syntax (iOS 10+)
    let timer = Timer(timeInterval: 0.4, repeats: true) { _ in print("Done!") }
    // Swift >=3 selector syntax
    let timer = Timer.scheduledTimer(timeInterval: 0.4, target: self, selector: #selector(self.update), userInfo: nil, repeats: true)
    // Swift 2.2 selector syntax
    let timer = NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: #selector(MyClass.update), userInfo: nil, repeats: true)
    // Swift <2.2 selector syntax
    let timer = NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: "update", userInfo: nil, repeats: true)
}

// must be internal or public. 
@objc func update() {
    // Something cool
}

Swift 4의 경우, 선택기를 가져 오려는 메소드는 Objective-C에 노출 @objc되어야 하므로 메소드 선언에 속성을 추가해야합니다.


2
이 메소드를 가진 클래스는 NSObject 여야한다고 덧붙였다. 그렇지 않으면 인식 할 수없는 선택기 오류가 발생한다
Joshua

27
Xcode 6.1부터는 "@objc func update () {"와 같이 함수 헤더에 "@objc"를 추가해야했습니다. 그것 없이는 첫 번째 화재시 앱이 충돌합니다.
kev

Var timer를 선언 할 수 있습니다 : NSTimer! 처음에는 필요할 때마다 사용하십시오!
Nigilan

1
더 유용한 블록 구문 버전 : let timer = Timer.scheduledTimer (withTimeInterval : timeout, repeats : false) {_ in print ( "Done.")}
Teo Sartori

'let timer = Timer (timeInterval : 0.4, repeats : true) {_ in print ( "Done!")}'를 사용할 수 없습니다. 타이머가 시작되지 않아 반복 할 수 없습니다. Timer.scheduledTimer를 사용해야합니다.
Siamaster

149

반복되는 이벤트

다음 예제와 같이 타이머를 사용하여 작업을 여러 번 수행 할 수 있습니다. 타이머는 매 0.5 초마다 레이블을 업데이트하는 메소드를 호출합니다.

여기에 이미지 설명을 입력하십시오

그 코드는 다음과 같습니다.

import UIKit

class ViewController: UIViewController {

    var counter = 0
    var timer = Timer()

    @IBOutlet weak var label: UILabel!

    // start timer
    @IBAction func startTimerButtonTapped(sender: UIButton) {
        timer.invalidate() // just in case this button is tapped multiple times

        // start the timer
        timer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
    }

    // stop timer
    @IBAction func cancelTimerButtonTapped(sender: UIButton) {
        timer.invalidate()
    }

    // called every time interval from the timer
    func timerAction() {
        counter += 1
        label.text = "\(counter)"
    }
}

지연된 이벤트

타이머를 사용하여 나중에 일정 시간 동안 한 번만 이벤트를 예약 할 수도 있습니다. 위 예제와의 주요 차이점은 repeats: false대신에 사용 한다는 것입니다 true.

timer = Timer.scheduledTimer(timeInterval: 2.0, target: self, selector: #selector(delayedAction), userInfo: nil, repeats: false)

위의 예제 delayedAction는 타이머가 설정된 후 2 초라는 이름의 메서드를 호출합니다 . 반복되지는 않지만 timer.invalidate()이벤트가 발생하기 전에 취소해야하는 경우 에도 전화를 걸 수 있습니다 .

노트

  • 타이머 인스턴스를 여러 번 시작할 가능성이있는 경우 먼저 이전 타이머 인스턴스를 무효화해야합니다. 그렇지 않으면 타이머에 대한 참조가 없어지고 더 이상 중지 할 수 없습니다. ( 이 Q & A 참조 )
  • 타이머가 필요 없을 때는 사용하지 마십시오. iOS 앱 에너지 효율 가이드 의 타이머 섹션을 참조하십시오 .

관련


1
@raddevus, 알려 주셔서 감사합니다. 이전 Swift 3 주석을 제거했습니다.
Suragch

31

userInfo를 활용하여 Swift 4로 업데이트되었습니다.

class TimerSample {

    var timer: Timer?

    func startTimer() {
        timer = Timer.scheduledTimer(timeInterval: 5.0,
                                     target: self,
                                     selector: #selector(eventWith(timer:)),
                                     userInfo: [ "foo" : "bar" ],
                                     repeats: true)
    }

    // Timer expects @objc selector
    @objc func eventWith(timer: Timer!) {
        let info = timer.userInfo as Any
        print(info)
    }

}

2
실제 예를 보여주십시오. "custom"과 "data"는 함수가 NSTimer객체를 기대할 경우 무엇을 의미하는지
Carlos.V

1
정말 중요하지 않습니다. 필요한 것을 userInfo 사전에 자유롭게 저장할 수 있습니다.이 경우 임의의 키-값 쌍입니다.
igraczech

이것은 유용하지만 Swift 3에서 작동했습니다. 예 : Timer.scheduledTimer (timeInterval : 1.0, target : self, selector : #selector (event), userInfo : "Info Sent", repeats : true)
Bobby

28

iOS 10부터는 선택기를 사용하는 것보다 깨끗한 새로운 블록 기반 타이머 팩토리 방법이 있습니다.

    _ = Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { timer in
        label.isHidden = true
    }

1
당신이하는 방식으로, 그냥 제거하고 _ = 시작 하는 것이 낫지 Timer않습니까?
Honey

2
사용하지 않는 값에 대해 경고를 표시하지 않거나 경고 만 신경 쓰지 않으면 _ =를 생략 할 수 있습니다. 경고가있는 코드를 체크인하고 싶지 않습니다.
Josh Homann

22

스위프트 3, iOS 10 이전

func schedule() {
    DispatchQueue.main.async {
      self.timer = Timer.scheduledTimer(timeInterval: 20, target: self,
                                   selector: #selector(self.timerDidFire(timer:)), userInfo: nil, repeats: false)
    }
  }

  @objc private func timerDidFire(timer: Timer) {
    print(timer)
  }

스위프트 3, iOS 10+

DispatchQueue.main.async {
      self.timer = Timer.scheduledTimer(withTimeInterval: 20, repeats: false) { timer in
        print(timer)
      }
    }

노트

  • 메인 큐에 있어야합니다
  • 콜백 함수는 공개, 비공개, ...가 될 수 있습니다.
  • 콜백 함수는 @objc

1
내 이해는 타이머 콜백 만 메인 큐에 있어야하고 다음이 약간 더 효율적이라는 것입니다. self.timer = Timer.scheduledTimer (withTimeInterval : 20, repeats : false) {timer in DispatchQueue.main.async {print (타이머)}}
Mathieu Frenette

내 타이머가 내 개체 중 하나에서 트리거되지 않아 트릭을 만들었습니다.)
Reimond Hill

@ReimondHill 변경해야합니다timeInterval
onmyway133

17

확인 :

스위프트 2

var timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("update"), userInfo: nil, repeats: true)

스위프트 3, 4, 5

var timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(self.update), userInfo: nil, repeats: true)

2
이미 시도했지만 '제공된 인수를 허용하는'init '에 대한 과부하를 찾을 수 없습니다'
user3225917

1
여기서도 '제공된 인수를 허용하는'init '에 대한 과부하를 찾을 수 없습니다'라는 오류가 발생했습니다. 이 라인은 실제로 작동합니까?
Yangshun Tay

@yangshun과 같은 오류가 발생합니다. 어떤 유형의 객체 여야 self합니까? UIView는 괜찮습니까?
SimplGy

@SimpleAsCouldBe : 네, 괜찮습니다
Midhun MP

func amountSubmitSuccess () {self.view.hideToastActivity () self.view.makeToast (message : "The Amount Successfully Registered") var timer = NSTimer.scheduledTimerWithTimeInterval (0.5, 대상 : self, 선택기 : "moveToBidderPage", userInfo : nil, 반복 : false)} func moveToBidderPage () {let loginPageView = self.storyboard? .instantiateViewControllerWithIdentifier ( "bidderpageID") as! BidderPage self.navigationController? .pushViewController (loginPageView, animated : true)}
AG

11

Swift 3에서 NSTimer 대신 Timer 를 사용해야 합니다.

예를 들면 다음과 같습니다.

Timer.scheduledTimer(timeInterval: 1, 
    target: self, 
    selector: #selector(YourController.update), 
    userInfo: nil, 
    repeats: true)

// @objc selector expected for Timer
@objc func update() {
    // do what should happen when timer triggers an event
}

11

스위프트 5

나는 개인적으로 블록 클로저가있는 타이머를 선호합니다.

    Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { (_) in
       // TODO: - whatever you want
    }

이것은 macOS 10.12 이상에서만 사용할 수 있습니다. iOS에 대해 확실하지 않습니다.
jeff-h

iOS에서도 사용할 수 있습니다.
Wissa

7

swift 3 및 Xcode 8.2의 경우 (블록을 ​​가지고 있지만 iOS9 용으로 컴파일하고 userInfo를 원할 경우) :

...

        self.timer = Timer(fireAt: fire,
                           interval: deltaT,
                           target: self,
                           selector: #selector(timerCallBack(timer:)),
                           userInfo: ["custom":"data"],
                           repeats: true)

        RunLoop.main.add(self.timer!, forMode: RunLoopMode.commonModes)
        self.timer!.fire()
}

func timerCallBack(timer: Timer!){
        let info = timer.userInfo
        print(info)
    }

6

SimpleTimer (Swift 3.1)

왜?

이것은 신속하게 간단한 타이머 클래스로 다음을 수행 할 수 있습니다.

  • 로컬 범위 타이머
  • 체인 가능
  • 하나의 라이너
  • 정기적 인 콜백 사용

용법:

SimpleTimer(interval: 3,repeats: true){print("tick")}.start()//Ticks every 3 secs

암호:

class SimpleTimer {/*<--was named Timer, but since swift 3, NSTimer is now Timer*/
    typealias Tick = ()->Void
    var timer:Timer?
    var interval:TimeInterval /*in seconds*/
    var repeats:Bool
    var tick:Tick

    init( interval:TimeInterval, repeats:Bool = false, onTick:@escaping Tick){
        self.interval = interval
        self.repeats = repeats
        self.tick = onTick
    }
    func start(){
        timer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(update), userInfo: nil, repeats: true)//swift 3 upgrade
    }
    func stop(){
        if(timer != nil){timer!.invalidate()}
    }
    /**
     * This method must be in the public or scope
     */
    @objc func update() {
        tick()
    }
}

그런 다음 일부 조건에서 해당 블록 내부의 타이머를 중지하는 방법은 무엇입니까?
모바일 개발자 iOS Android

클래스의 타이머에 심판을 저장하고 중지를 호출하십시오. xcode 컴파일러는 이스케이프 등이 필요한지 알려줍니다.
eonist

3
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(createEnemy), userInfo: nil, repeats: true)

이름으로 재미있는 만들기 createEnemy

fund createEnemy ()
{
do anything ////
}

3

먼저 타이머를 선언하십시오

var timer: Timer?

그런 다음 viewDidLoad () 또는 타이머를 시작하려는 함수에 줄을 추가하십시오.

timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(action), userInfo: nil, repeats: false)

이것은 @objc이어야하는 것을하기 위해 콜백 할 함수입니다.

@objc func action () {
print("done")
}

2

Swift 3 에서는 @objc를 사용하여 다음과 같이합니다.

func startTimerForResendingCode() {
    let timerIntervalForResendingCode = TimeInterval(60)
    Timer.scheduledTimer(timeInterval: timerIntervalForResendingCode,
                         target: self,
                         selector: #selector(timerEndedUp),
                         userInfo: nil,
                         repeats: false)
}




@objc func timerEndedUp() {
    output?.timerHasFinishedAndCodeMayBeResended()
}

1

타이머를 초기화하면

let timer = Timer(timeInterval: 3, target: self, selector: #selector(update(_:)), userInfo: [key : value], repeats: false)

func update(_ timer : Timer) {

}

그런 다음 다른 선택기가 호출되지 않는 메소드를 사용하여 루프에 추가하십시오.

RunLoop.main.add(timer!, forMode: .defaultRunLoopMode)

참고 : 이것을 반복하려면 반복을 참으로 만들고 타이머의 참조를 유지하십시오. 그렇지 않으면 update 메소드가 호출되지 않습니다.

이 방법을 사용하는 경우

Timer.scheduledTimer(timeInterval: seconds, target: self, selector: #selector(update(_:)), userInfo: nil, repeats: true)

반복이 참인 경우 나중에 사용하기 위해 참조를 유지하십시오.


0

NSObject 클래스에서 시도했지만 이것이 나를 위해 일했습니다.

DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(300)) {  
print("Bang!") }

-2

NSTimer는 Swift 4.2에서 Timer로 이름이 변경되었습니다. 이 구문은 4.2에서 작동합니다.

let timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(UIMenuController.update), userInfo: nil, repeats: true)

이름 변경은 스위프트에서 일어난 3 과 다른 답변은 이미 ... 업데이트를 수행 한
에릭 아야를
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.