-
Star
(108)
You must be signed in to star a gist -
Fork
(3)
You must be signed in to fork a gist
-
-
Save natecook1000/b0285b518576b22c4dc8 to your computer and use it in GitHub Desktop.
| extension NSTimer { | |
| /** | |
| Creates and schedules a one-time `NSTimer` instance. | |
| - Parameters: | |
| - delay: The delay before execution. | |
| - handler: A closure to execute after `delay`. | |
| - Returns: The newly-created `NSTimer` instance. | |
| */ | |
| class func schedule(delay delay: NSTimeInterval, handler: NSTimer! -> Void) -> NSTimer { | |
| let fireDate = delay + CFAbsoluteTimeGetCurrent() | |
| let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, 0, 0, 0, handler) | |
| CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes) | |
| return timer | |
| } | |
| /** | |
| Creates and schedules a repeating `NSTimer` instance. | |
| - Parameters: | |
| - repeatInterval: The interval (in seconds) between each execution of | |
| `handler`. Note that individual calls may be delayed; subsequent calls | |
| to `handler` will be based on the time the timer was created. | |
| - handler: A closure to execute at each `repeatInterval`. | |
| - Returns: The newly-created `NSTimer` instance. | |
| */ | |
| class func schedule(repeatInterval interval: NSTimeInterval, handler: NSTimer! -> Void) -> NSTimer { | |
| let fireDate = interval + CFAbsoluteTimeGetCurrent() | |
| let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, interval, 0, 0, handler) | |
| CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes) | |
| return timer | |
| } | |
| } | |
| // Usage: | |
| var count = 0 | |
| NSTimer.schedule(repeatInterval: 1) { timer in | |
| print(++count) | |
| if count >= 10 { | |
| timer.invalidate() | |
| } | |
| } | |
| NSTimer.schedule(delay: 5) { timer in | |
| print("5 seconds") | |
| } |
Just a minor styling addition, I think scheduledTimerWithTimeInterval is too long for a method name and could be easily replaced here by schedule(interval: repeats).
So I'd prefer using it like NSTimer.schedule(interval: 1, repeats: true) which is more concise, yet as clear. (more thoughts on Swift method naming here)
@rinatkhanov, I like that idea too. I've split the original method into NSTimer.schedule(delay:handler:) and NSTimer.schedule(repeatInterval:handler:).
how can I use this extension to reset and restart the timer every 20 seconds? The method will be inserted in a UIButton action. Thanks!
This is what I'm running for Swift 3.0:
extension Timer {
/**
Creates and schedules a one-time `NSTimer` instance.
:param: delay The delay before execution.
:param: handler A closure to execute after `delay`.
:returns: The newly-created `NSTimer` instance.
*/
class func schedule(delay: TimeInterval, handler: @escaping (Timer?) -> Void) -> Timer {
let fireDate = delay + CFAbsoluteTimeGetCurrent()
let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, 0, 0, 0, handler)!
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.commonModes)
return timer
}
/**
Creates and schedules a repeating `NSTimer` instance.
:param: repeatInterval The interval between each execution of `handler`. Note that individual calls may be delayed; subsequent calls to `handler` will be based on the time the `NSTimer` was created.
:param: handler A closure to execute after `delay`.
:returns: The newly-created `NSTimer` instance.
*/
class func schedule(repeatInterval interval: TimeInterval, handler: @escaping (Timer?) -> Void) -> Timer {
let fireDate = interval + CFAbsoluteTimeGetCurrent()
let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, interval, 0, 0, handler)!
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.commonModes)
return timer
}
}Also from iOS 10, there is a native method on Timer that does this: Timer.scheduledTimer(withTimeInterval: TimeInterval, repeats: Bool, block: (Timer) -> Void)
Great suggestion, thanks! Makes the wrapper around the closure completely unnecessary.