why is my custom UIButton subclass not triggering touch up IBAction? - swift

this probably has something to do with the fact that I am overriding touchesBegan in my custom subclass:
class myCustomButton: UIButton {
override open func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
print("TOUCHES BEGAN OVERRIDE CALLED")
originalColor = self.backgroundColor ?? .red
self.backgroundColor = .white
self.animateScale()
setNeedsDisplay()
}
//...
}
touchesEnded is similarly overridden, and both of these functions are called and print debug statements to console on button press. however, the code in the button pressed IBAction from my view controller is never run
#IBAction func nextButtonPressed(_ sender: Any) {
print("this is never executed")
//...
}
I have double checked that the IBOutlet is not broken and changed the (_ sender: Any) to (_ sender: AnyObject) both to no avail. any insights would be appreciated

ah ok, figured it out. in my custom button initializer I added a subview which, by default, had userInteractionEnabled set to true. setting userInteractionEnabled = true on my custom button object and userInteractionEnabled = false on my view before adding it as a subview allows my custom button to capture the touch and handle it properly rather than the view capturing the touch

Instead of overriding touchesBegan, try overriding the sendAction function of your UIButton:
override func sendAction(_ action: Selector, to target: Any?, for event: UIEvent?) {
super.sendAction(action, to: target, for: event)
//Insert your code here
}

Related

why touchesBegan event in 1stVC triggered by touch from 2ndVC?

I met a very strange thing:
in storyboard has to ViewControllers : 1stVC and 2ndVC,
in 1stVC (Initial VC in storyboard) only have 2 functions:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//when touch view in 2ndVC,it will exec here!!!
super.touchesBegan(touches, with: event)
NSLog("xxx")
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
//switch to 2ndVC
performSegue(withIdentifier: "2ndVC", sender: nil)
}
Because app starts from 1stVC,but at viewDidAppear func it's soon to go to exec performSegue() func to switch to 2ndVC;now app should be in 2ndVC,but when I touch the screen (at 2ndVC's view), it will jump to the 1stVC's touchsBegin func (exec NSLog("xxx")).
How could that happen!? please help me,thanks!!!

UITableView tapgesture behaviour

When I tap on my table view it will trigger touchesBegan and touchesShouldBegin. However, I also have a UIPanGestureRecognizer on my view cells and when panning a cell, tapping on other cells won't trigger touchesShouldBegin.
The reason I need touchesShouldBegin is because I want to stop the touches when a cell is being panned. Is there other methods I can use to do this? I have tried having set allowsMultipleSelection to false and true.
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
print("This will always be printed")
}
override func touchesShouldBegin(_ touches: Set<UITouch>, with event: UIEvent?, in view: UIView) -> Bool {
print("This will only be printed when no cells are being panned")
return true
}
Try to set the UITableView's delaysContentTouches property to true.
You can also try to add the a UIGestureRecognizerDelegate to your UIPanGestureRecognizer and have :
extension MyViewController: UIGestureRecognizerDelegate {
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}

UITextView keyboard is taking 2 taps to open.

I have a UITextView with a label over it as a placeholder. When the user taps on the UITextView the label disappears but for the keyboard to appear it takes another 2 taps. When I remove the tap gesture that hides the label the keyboard works perfectly. Here is my code any ideas as to what the problem is???
var tapTerm:UITapGestureRecognizer = UITapGestureRecognizer()
override func viewDidLoad() {
super.viewDidLoad()
bioTextfield.delegate = self
tapTerm = UITapGestureRecognizer(target: self, action: "tapTextView:")
// bioPlaceholderLabel.addGestureRecognizer(tapTerm)
bioTextfield.addGestureRecognizer(tapTerm)
}
func tapTextView(sender:UITapGestureRecognizer) {
// hide placeholder label text
bioPlaceholderLabel.text = ""
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// when user touches outside the keyboard close the keyboard
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.view.endEditing(true)
}
// when user presses the return button close the keyboard
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
if text == "\n" {
textView.resignFirstResponder()
return false
}
return true
}
Any help would be greatly appreciated!
Easier way, you should use this custom UITextView (with place holder): KMPlaceholderTextView. I'm using, so great.

in swift how to dismiss the key board

I am wondering how to dismiss a key board if the user touches outside the UITextField. I am using Xcode 6.1. I added a UITextField to a UIViewController as per the below thru ViewDidLoad() function. Any help on dismissing the key board would be much appreciated.
class PickerdemoViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate, UITextFieldDelegate{
var textBox1 : UITextField!
override func viewDidLoad() {
//..................adding text box.........................//
self.textBox1 = UITextField (frame: CGRectMake(100, 152.5, 50, 35))
textBox1.delegate = self
textBox1.backgroundColor = UIColor.whiteColor()
textBox1.placeholder = "enter"
textBox1.keyboardType = UIKeyboardType.DecimalPad
self.textBox1.resignFirstResponder()
textBox1.keyboardAppearance = UIKeyboardAppearance.Default
self.view.addSubview(textBox1)
super.viewDidLoad()
}
You need to have a reference to the UITextField so make a property value like this
class MyClass: UIViewController {
var textBox1: UITextField!
...
// create your textfield where ever you were by assigning it to self.textBox1
}
Then to dismiss the keyboard you resign its as the first responder.
self.textBox1.resignFirstResponder()
Update to dimiss keyboard
Dismissing on return/done with the textField delegate method
func textFieldShouldReturn(textField: UITextField) -> Bool {
self.textBox1.resignFirstResponder()
return true
}
Dismissing on a button click (custom IBAction method)
#IBAction func buttonClicked(sender: UIButton!) {
self.textBox1.resignFirstResponder()
}
This will dismiss the keyboard by tapping screen. Make sure to not put it in the viewDidLoad.
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { // this func lets you close keyboard by touching screen
self.view.endEditing(true) // this line lets you close keyboard by touching screen
}

dismissViewController with button in swift

So I am wondering what func to use for closing a detailed ViewController opened from a tableView. Currently I have it working to close the view, but the touches event occurs when you touch anywhere on the screen, not with a specific button. I have tried just using the button on storyboards but no luck. Below is what I have working so far (again not button specific)...
//DetailedViewController.swift
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
self.dismissViewControllerAnimated(true, completion: nil)
}
Any and all feedback or direction is greatly appreciated!
#IBAction func buttonAction(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
}
Put the button in the storyboard view controller and right-click-drag from the little circle for this action to the button. Alternatively, create your button programmatically and call addTarget(self, action:"buttonAction:") on the button.