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
}
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
How to Print Out a Property's Contents Using Xcode Debugger
Avplayer with Playback Controls of Avplayerviewcontroller
Remove Uiwebview's Internal Cache
Confirm Back Button on Uinavigationcontroller
Check If 3D Touch Is Supported and Enabled on the iOS9 Device
Bypass Code Signing with Xcode 6
iOS - Spritekit - How to Calculate the Distance Between Two Nodes
Installing Openssl Library for Xcode
Mkmapview Doesn't Zoom Correctly While User Tracking Mode Is Mkusertrackingmodefollowwithheading
Insert String at Cursor Position of Uitextfield
Code Signing Issue in Xcode Version 8
How to Take Uiimage of Avcapturevideopreviewlayer Instead of Avcapturephotooutput Capture
Xcode 4.2 Mainstoryboard Not Found
How to Get All Nsrange of a Particular Character in a Nsstring
iPhone Mkmapview - Mkpolygon Issues
Get Google Contacts Using API on iOS