source

Swift에서 Timer(기존 NSTimer)를 사용하려면 어떻게 해야 하나요?

manysource 2023. 4. 20. 21:36

Swift에서 Timer(기존 NSTimer)를 사용하려면 어떻게 해야 하나요?

나는 노력했다.

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'

이 조작은 유효합니다.

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메서드 선언에 속성을 추가해야 합니다.

반복 이벤트

다음 예시와 같이 타이머를 사용하여 액션을 여러 번 수행할 수 있습니다.타이머는 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 앱용 에너지 효율 가이드의 타이머 섹션을 참조하십시오.

관련된

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

}

iOS 10에서는 셀렉터를 사용하는 것보다 더 깨끗한 새로운 블록 기반 타이머 공장 방식도 있습니다.

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

스위프트 5

개인적으로 블록 폐쇄 기능이 있는 타이머를 선호합니다.

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

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

Swift 3, iOS 10 이상

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

메모들

  • 메인 큐에 있어야 합니다.
  • 콜백 함수는 퍼블릭, 프라이빗 등입니다.
  • 콜백 함수는@objc

확인 대상:

스위프트 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)

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
}

먼저 타이머를 선언합니다.

var timer: Timer?

그런 다음 viewDidLoad() 또는 타이머를 시작할 함수에 행을 추가합니다.

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

이 함수는 @objc여야 하는 작업을 수행하기 위해 호출하는 함수입니다.

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

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

SimpleTimer (Swift 3.1)

왜요?

이것은 간단한 타이머 클래스이며, 다음과 같은 작업을 수행할 수 있습니다.

  • 로컬 스코프 타이머
  • 체인 가능
  • 라이너 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()
    }
}
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(createEnemy), userInfo: nil, repeats: true)

Create Enemy라는 이름의 Create Fun을 만듭니다.

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

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

타이머의 초기화 방법을 사용하는 경우

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)

메모: 반복할 경우 true로 만들고 타이머 참조를 유지합니다.그렇지 않으면 업데이트 메서드가 호출되지 않습니다.

이 방법을 사용하는 경우.

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

반복이 참일 경우 나중에 사용할 수 있도록 참조를 보관합니다.

NSObject 클래스에서 하려고 했는데, 이 방법이 효과가 있었습니다.

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

다음으로 UIButton을 눌렀을 때 생성되는 기본 Timer 객체의 예를 나타냅니다(Swift 5.x의 경우).닫힘을 사용하여 현재 타이머 값을 로그에 출력하고 최종적으로 invalidate()를 호출하여 타이머를 중지하고 실행 루프에서 제거합니다.

@IBAction func startTimer(_ sender: UIButton) {
    var runCount = 60 //for a 60 second timer
    
    Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
        print(runCount)
        runCount -= 1

        if runCount < 0 {
            timer.invalidate()
        }
    }
    
}

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

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

언급URL : https://stackoverflow.com/questions/24007518/how-can-i-use-timer-formerly-nstimer-in-swift