Reputation: 791
class TimerFactory {
var second: Int = 0;
var timer: Timer = Timer();
init(second: Int) {
if(second > 0) {
self.second = second;
}
}
func runTimer(_ vc: ViewController) -> Void {
self.timer = Timer.scheduledTimer(timeInterval: 1, target: vc, selector: (#selector(vc.updateViewTimer)), userInfo: nil, repeats: true)
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
@objc func updateViewTimer() {
print("Hello")
}
}
extension ViewController {
@IBAction func startCounter(_ sender: UIBarButtonItem) {
let timer = TimerFactory(second: 60);
timer.runTimer(self)
}
}
Sory for my question I'm new in SWIFT But i want to create timer but timer selector call my ViewController updateViewTimer but this code return false but self.test work What is problem in here?
Upvotes: 0
Views: 730
Reputation: 20234
Your target should be vc
as that's where the timer will look for the method updateViewTimer
.
func runTimer(_ vc: ViewController) -> Void {
self.timer = Timer.scheduledTimer(timeInterval: 1,
target: vc,
selector: (#selector(vc.updateViewTimer)),
userInfo: nil,
repeats: true)
}
When target was self
it referred to TimerFactory
.
EDIT (based on comments):
func runTimer(_ vc: ViewController) -> Void {
self.timer = Timer.scheduledTimer(timeInterval: 1,
target: vc,
selector: (#selector(vc.updateViewTimer(timer:))),
userInfo: self,
repeats: true)
}
@objc func updateViewTimer(_ timer: Timer) {
if let factory = timer.userInfo as? TimerFactory {
factory.second -= 1
print(factory.second)
if factory.second == 0 {
print("completed")
timer.invalidate()
}
}
}
EDIT 2 (suggestion):
If you plan to reuse TimerFactory
in another class then you'd need to ensure that updateViewTimer()
method exists in this class or else the code will crash.
Instead... I would rather suggest a more robust approach that will use a closure and drop the dependency on the updateViewTimer(_:)
method:
func runTimer(_ vc: ViewController, updateHandler: @escaping (_ second: Int)->Void) -> Void {
self.timer = Timer.scheduledTimer(withTimeInterval: 1,
repeats: true,
block: { (timer) in
self.second -= 1
updateHandler(self.second)
if self.second == 0 {
timer.invalidate()
}
})
}
func startCounter() {
let timer = TimerFactory(second: 10);
timer.runTimer(self) { (second) in
print(second)
if second == 0 {
print("completed")
}
}
}
Upvotes: 1
Reputation: 100503
The problem is that the target should contain the method to be invoked , in timer declaration you set it to self , so it will look for a method inside that class , can you try
self.timer = Timer.scheduledTimer(timeInterval: 1, target: vc , selector: (#selector(vc.updateViewTimer)), userInfo: nil, repeats: true)
Upvotes: 0