UITapGestureRecogniser add target not working - swift

i have a objc function:
#objc private func segmentedControlViewTapped(gestureRecognizer: UITapGestureRecognizer)
I am trying to add this as a target for a gestureRecognizer but the code keeps crashing when i tap the segment control.
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(SegmentedControl.segmentedControlViewTapped(gestureRecognizer:)))
crashes due to: unrecognized selector sent

The action needs to point to a function in the target you specified.
Assuming the segmentedControlViewTapped is in your view or controller, change your code like this:
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(segmentedControlViewTapped(gestureRecognizer:)))

Related

iOS selector not getting called for UIBarButtonItem

I've got some fairly simple code, and am trying to figure out why the uibarbuttonitem isn't triggering the selector:
TableView's viewDidLoad method:
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
self.clearsSelectionOnViewWillAppear = false
// this line adds a button to top right
let addNewChecklistItemButton = UIBarButtonItem(barButtonSystemItem: .add,
target: nil,
action: #selector(self.addNewChecklistItemToDataModel))
self.navigationItem.rightBarButtonItem = addNewChecklistItemButton
}
Method called:
#objc func addNewChecklistItemToDataModel() {
print("adding new item...")
<...>
}
The button is being added (was not visible before I put this code in) and when I press it the button click animates but my console doesn't show the printed text.
After reading UIBarButtonItem selector not working, I'm wondering if the fact that my UITableViewController is embedded in both a UITabViewController and UINavigationViewController is effecting the button's scope? If not, anyone see something I'm missing?
Target shouldn't be nil
let addNewChecklistItemButton = UIBarButtonItem(barButtonSystemItem: .add,
target: self,
action: #selector(self.addNewChecklistItemToDataModel))

Gesture recognizer issues

I'm having trouble wrapping my brain around gesture recognizers. I want to target a subview. Here's an example that works with the main view:
let gesture = UITapGestureRecognizer(target: hex_pin_view!, action: #selector(openEmojis(sender:)))
gesture.delegate = self
mapView.addGestureRecognizer(gesture)
Here's the subview target, this dose not work and is what I'm looking for:
let gesture = UITapGestureRecognizer(target: hex_pin_view!.add_emoji_img_view, action: #selector(openEmojis(sender:)))
gesture.delegate = self
mapView.addGestureRecognizer(gesture)
I'm getting a crash error:
unrecognized selector sent to instance
Tho the selector is the same, I don't get it.
Anyone have a clue what I could be doing wrong?
The target of a gesture recogniser is the object that will receive messages from the gesture recogniser. or simply put, the object that holds the function that will handle the message.
Alot of the time the target: is set to self.
selector is the function/method that will handle the messages.
let gesture = UITapGestureRecognizer(target: self, action: #selector(openEmojis(sender:)))
gesture.delegate = self
mapView.addGestureRecognizer(gesture)
So there, the currrent class/object should have a method called openEmojis. The gesture is added to the mapView here
mapView.addGestureRecognizer(gesture)
So when the map gets tapped, your function should be called.
If you want the gesture to trigger when your subview is tapped. instead add the gesture recogniser to the subview instead:
add_emoji_img_view.addGestureRecognizer(gesture)

Tap Gesture isn't working. User interaction enabled.

Have following view structure:
Programmatically adding tap gesture rec to Temp lbl:
let tempLblTap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(MainFeedVC.convertDegrees))
tempLblTap.delegate = self
tempLblTap.numberOfTapsRequired = 1
tempLblTap.numberOfTouchesRequired = 1
tempLblTap.cancelsTouchesInView = false
self.tempLbl.isUserInteractionEnabled = true
self.tempLbl.addGestureRecognizer(tempLblTap)
but the method convertDegrees isn't triggered.
There are also 2 swipe gesture recognizers that are added to the same view:
let leftSwipeGestureRecognizer: UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(MainFeedVC.showPostPicVC))
leftSwipeGestureRecognizer.direction = UISwipeGestureRecognizerDirection.left
self.view.addGestureRecognizer(leftSwipeGestureRecognizer)
let rightSwipeGestureRecognizer: UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(MainFeedVC.showUserVC))
rightSwipeGestureRecognizer.direction = UISwipeGestureRecognizerDirection.right
self.view.addGestureRecognizer(rightSwipeGestureRecognizer)
Maybe they are the reason?
Found solution:
View that contained my lbl had its userInteractionEnabled unchecked in storyboards.
So, when adding gesture recognizers to labels, images or simply adding buttons, always check that all parent views has its userInteractionEnabled to true.

How to create a plus symbol bar button item

How do you create UIBarButtonItem as a plus symbol? I tried giving it the title "+", but I would like it to look more like the plus symbol you would normally create if you used storyboard. Which doesn't have a background or an underline.
It's one of the provided bar button system items.
let addBarButton = UIBarButtonItem(barButtonSystemItem: .add, target: YOUR_TARGET, action: YOUR_SELECTOR)
I think this is what you are looking for:
Swift 4.2 Example
Here is how you do it:
let addBarButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addUser))
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.rightBarButtonItem = addBarButton
}
#objc private func addUser() {
// Some code, e.g.
let storyboard = UIStoryboard(name: "CreateNewUser", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "createUser") as! CreateUserVC
self.navigationController?.pushViewController(vc, animated: true)
}
IMPORTANT NOTE: There is a little problem though which many users have pointed out and took me many hours to figure out as well (for iOS 11, 12) that you must put the self.navigationItem.rightBarButtonItem = addBarButton inside the viewDidLoad function otherwise the button's selector won't work. This has something to do, as per other users on StackOverflow, with tap gestures. In my code, one of my view controllers have two buttons assigned outside of viewDidLoad function but there is also use a function to hide the keyboard, which probably causes the buttons to work fine. However, in view controllers of two other projects where I don't show or hide keyboard, the #selector for programatically set navigation bar buttons don't work unless they are defined within viewDidLoad function as in the example above. I hope this tip will save you tons of time in case you face this problem.
Swift 3.0
let addBarButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(ViewController.openSearch))

About UITapGestrueRecognizer in Swift

I have made a view subclass of UIView.Then, I added UITapGestureRecognizer to it but when I tap on the view, it don't respond to it.
Code:
let tapGesture = UITapGestureRecognizer(target: self, action: "singleTapHandler:")
self.maskView!.addGestureRecognizer(tapGesture)
selector:
func singleTapHandler(recognizer: UITapGestureRecognizer) {
print("xxx")
dismiss()
}
Ensure that you have enabled user interactivity:
self.maskView!.userInteractionEnabled = true
Make sure the maskView on top of the view, and the frame not equals to CGRectZero
Check if you added UIGestureRecognizerDelegate to your view, and use that tapGesture.delegate = self
Your tapGesture should be like let tapGesture = UITapGestureRecognizer(target: self, action: "singleTapHandler"), there is no need of :
Then your function can
func singleTapHandler(){
//action
}
Lastly, make sure you tap on the view you added the tap gesture.