How to Pass Params on Timer Selector

How do I pass params on timer selector

For sending the data with Timer you can use the userInfo parameter for pass the data.

Here is the sample by which you can get call of selector method and by that you can pass your location coordinate to it.

Timer.scheduledTimer(timeInterval: 0.5, target: self, selector:#selector(iGotCall(sender:)), userInfo: ["Name": "i am iOS guy"], repeats:true)

For handling that userInfo you need to go according to below.

func iGotCall(sender: Timer) {
print((sender.userInfo)!)
}

for your case make sure your didUpdateLocations is called frequently.

How can I send parameter with #selector

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

Use selector to call function with parameters

EDIT: Updating to include pre-iOS 10.0 solution

In this case it'd be better to use the scheduledTimer function that takes a block, as this will allow you to pass arguments to your function:

Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { (timer) in
SystemClass().setXYZ(xyz: 1.0)
}

For pre-iOS 10.0:

You can also pass userInfo in, including this default value, and then access that info from your inside your selector, like this:

Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(SystemClass().setXYZ(_:)), userInfo: 1.0, repeats: true)

To do this you'd also have to modify your setXYZ function signature to look like this:

@objc func setXYZ(_ sender: Timer) {
if let xyz = sender.userInfo as? Float {
print(xyz)
// do something
}
}

Passing trough arguments for a function as Selector for a scheduledTimer

You can use userInfo

self.timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: Selector(ViewController.update(_:)), userInfo: ["data" : youData], repeats: true)

And get it in your function:

func update(data: Timer) {
let userInfo = timer.userInfo as Dictionary<String, AnyObject>
let data = userInfo["data"]
//use your data
}

Passing parameters to the method called by a NSTimer

You need to define the method in the target. Since you set the target as 'self', then yes that same object needs to implement the method. But you could have set the target to anything else you wanted.

userInfo is a pointer that you can set to any object (or collection) you like and that will be passed to the target selector when the timer fires.

EDIT: ... Simple Example:

Set up the timer:

    NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval:2.0 
target:self
selector:@selector(handleTimer:)
userInfo:@"someString" repeats:NO];

and implement the handler in the same class (assuming you're setting the target to 'self'):

- (void)handleTimer:(NSTimer*)theTimer {

NSLog (@"Got the string: %@", (NSString*)[theTimer userInfo]);

}

Pass two arguments to NSTimer in Swift

Make a array with your objects and send it to userInfo. Try this:

func someFunc(){
var arr = ["one", "two"]
var timer: NSTimer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("val:"), userInfo: arr, repeats: true)

}

func val(timer: NSTimer){

//You'll get an array in timer.userInfo
// arr = timer.userInfo.
// Now you'll get you data in each index of arr

}

Hope this helps.. :)

Pass parameter to selector function in Swift

set your timer with the userinfo

timer = Timer.init(timeInterval: 1.0, target: self, selector: #selector(downloadTimer(cell: cell), userInfo: data, repeats: true)

and get userinfo as follow

func downloadTimer(_ timer: Timer) {
let data = timer.userInfo
}

------ EDIT ------

As per the below examples, but not getting expected results as usual from a cell

let innerCell: InnerCollectionCell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifierInner, for: indexPath) as! InnerCollectionCell

timer = Timer.init(timeInterval: 1.0, target: self, selector: #selector(downloadTimer(_:)), userInfo: innerCell, repeats: true)

func downloadTimer(_ timer: Timer) {

let cell = timer.userInfo as! InnerCollectionCell

cell. // no options as expected of a cell

}

Sample Image

Multiple parameters in NSTimer selector

You cannot pass more than one parameter using NSTimer, however, you can make that parameter into an array or ditionary or similar.

Then create a new function that takes that array/dictionary and then calls your function with every parameter inside the array/dictionary

func fireTimer() {
timer = NSTimer.scheduledTimerWithTimeInterval(4, target: self, selector: Selector("showAlert2:"), userInfo: ["title":"a title", "message": "a message", "controller": controller], repeats: false)
}

func showAlert2(timer: NSTimer) {
let dict = timer.userInfo as NSDictionary

showAlert(dict["title"] as String, wwithMessage: dict["message"] as String, fromController: dict["controller"] as UIViewController)
}

func showAlert(alertTitle: String, withMessage alertMessage: String, fromController controller: UIViewController) {
// do stuff...
}


Related Topics



Leave a reply



Submit