What is the proper syntax for action in swift 2? - ios

I have a function set like this:
func alertControllerBackgroundTapped(myString: String) {
///do something in here
})
}
which I am trying to invoke here:
alert.view.superview?.addGestureRecognizer(UITapGestureRecognizer(target: self, action:#selector(CICViewController.alertControllerBackgroundTapped(_:))))
But obviously this will gives me an error since I am not setting my arguments (myString) correctly.
What is the proper syntax in this?
many thanks

Since you are adding this action to UITapGestureRecognizer, the action must have a proper signature - a single-argument function taking UITapGestureRecognizer and not returning anything. Inside the recognizer body you are free to make a call to your function that takes a string:
func handleTap(recognizer: UITapGestureRecognizer) {
alertControllerBackgroundTapped("Hello!")
}
Add handleTap as the action instead of alertControllerBackgroundTapped:
alert.view.superview?.addGestureRecognizer(
UITapGestureRecognizer(
target: self
, action:#selector(CICViewController.handleTap(_:))
)
)

Related

iOS selector in Xamarin.iOS

I am trying to create an UIAccessibilityCustomAction in Xamarin.iOS. This method require name, target, selector as arguments (as you can see here). The problem is with the selector argument.
In Xcode (using Swift) I can easily implement it like this:
let up = UIAccessibilityCustomAction(name: "Increment", target: self, selector: #selector(increment))
#objc private func increment() -> Bool{
//selector implementation
}
In Xamarin (using C#) I tried that:
UIAccessibilityCustomAction up = new UIAccessibilityCustomAction(name: "Increment", target: iospage, selector: new Selector("Increment"));
And its being said that Selector can take both a String or a IntPtr as argument. Since I have no idea what IntPtr is and how should I use it, I tried to use the String parameter, as you can see above, and I tried to implement the selector like this, following this answer.
[Export("Increment")]
private void Increment()
{
//selector implementation
}
Problem is that seems like this method never got called (i tried to make it log something when the UIAccessibilityCustomAction is called, but no log is shown), probably because it is the wrong way to implement it.
Any idea?
Thanks
UIAccessibilityCustomAction has another instantiate method which you can pass an custom action into it .
UIAccessibilityCustomAction c = new UIAccessibilityCustomAction("Increment",
(UIAccessibilityCustomAction customAction) =>
{
//selector implementation
});
Thanks to the tip of #Cole Xia - MSFT, I found another instantiate method that seems to be easier to handle, using only name, actionHandler, so without a target and selector. actionHandler is easier to use, cause it's only a function that needs a bool return type.
My implementation:
UIAccessibilityCustomAction up = new UIAccessibilityCustomAction("Increment", actionHandler: Increment);
private bool Increment(UIAccessibilityCustomAction customAction)
{
//implementation of the handler
}

Xcode requests I use argument label when none defined in function?

I have this protocol which I go on to implement in my view controller.
protocol GuessDelegate {
func userDidFinish(_controller:GuessInputViewController, guess:String)
}
However, when I call it, the compiler forces me to type _controller: just before self (please see below). It doesn't allow me to write delegate.userDidFinish(self, guess: guessText) and complains about a missing argument label if I try that.
However, the method signature has no argument label, just a parameter name controller with a leading underscore which I thought meant the parameter name therefore doesn't need to be typed out in the call to the function.
What is going on exactly? Is it perhaps behaving like this because it's a protocol method?
#IBAction func saveGuess(_ sender: AnyObject) {
if let delegate = delegate, let guessText = guessTextField.text {
delegate.userDidFinish(_controller: self, guess: guessText)
}
}
put a space between underscore and controller
protocol GuessDelegate {
func userDidFinish(_ controller:GuessInputViewController, guess:String)
}

Function with Completion in Timer Selector

I am declaring a function as such:
#objc func fetchDatabase(completion: ((Bool) -> Void)? = nil)
I'm allowing the completion to be nil so I can either call it as fetchDatabase() or as
fetchDatabase(completion: { (result) in
// Stuff in here
})
However, I am also trying to use this function in a #selector for a Timer. I am creating this timer using the following line:
Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(fetchDatabase), userInfo: nil, repeats: true)
Without the completion, this runs fine. However, with the completion added, I get an EXC_BAD_ACCESS error whenever the timer is run. Some help with correctly constructing this selector would be greatly appreciated, if this is in fact the error.
The selector passed to the timer only allows one of two possible signatures
someFunction()
someFunction(someLabel someParameter: Timer)
You can't pass your fetchDatabase(completion:) function because it doesn't match either of the two legal selector signatures.
You need to pass a valid selector which in turn calls your fetchDatabase(completion:) function. For example:
#objc timerHandler() {
fetchDatabase(completion: { (result) in
// Stuff in here
})
}
use #selector(timerHandler) with your timer.
Default arguments get applied at the calling site, so you'll need to generate two separate methods (one of which calls the other):
func fetchDatabase() { fetchDatabase(callback:nil) }
func fetchDatabase(callback:()->()) {
...
}
Now your scheduledTimer call should work fine.

Swift 2.2 Selector with multiple arguments - actually passing in

I want to use a selector, but I need to pass in the arguments
I understand the syntax follows:
#selector(class.method(_:paramName:))
but i need to actually pass in parameters. How do I do this?
Here's my attempt:
exploreTap = UITapGestureRecognizer(target: self, action: #selector(MainViewController.showViewWithIdentifier(_:exploreView,id:"explore")))
You cannot pass parameters to selectors, selector is just a method name, nothing else. You are not calling the method so you cannot pass parameters.
Just call the necessary code inside your tap handler.
func onTap() {
MainViewController.showViewWithIdentifier(exploreView, id:"explore")
}
and then
UITapGestureRecognizer(target: self, action: #selector(onTap))

Check if node has actions being processed?

I'm executing the SKAction rotateToAngle on one method. On another method I want to know in whether the action is still being executed or if it has ended.
I could save the time the action started in a property and check it however I was wondering whether there is an easier method.
private func rotate(motionManager: CMMotionManager, gravity: CGVector) {
let rotate = SKAction.rotateToAngle(CGFloat(M_PI * 5), duration: 5.0, shortestUnitArc: true)
self.runAction(rotate)
}
private func actionRunning() --> Bool {
}
I tried using self.hasActions() but it always return true. Any ideas on how to do this on Swift?
You could always use the withKey parameter when using runAction. Then do a actionForKey: method to determine if it still exists.
In Objective-C it looks like this:
[self runAction:[SKAction waitForDuration:0.1] withKey:#"waitTimer"];
[self actionForKey:#"waitTimer"];
I'm not familiar with Swift, but the Apple Docs do show it supported for the Swift Language as well.
https://developer.apple.com/library/prerelease/ios/documentation/SpriteKit/Reference/SKNode_Ref/index.html#//apple_ref/occ/instm/SKNode/runAction:withKey:
func runAction(_ action: SKAction!,
withKey key: String!)

Resources