UITapGesture removing ability to select from UITableView when resigning keyboard responder - ios

So I'm having an issue where I have added a UITapGestureRecognizer to resign first responder status of associated textfields so the keyboard will drop away.
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(AddMedViewController.dismissKeyboard))
view.addGestureRecognizer(tap)
func dismissKeyboard() {
medNameText.resignFirstResponder()
doseAmountText.resignFirstResponder()
}
This works fine for getting rid of the keyboard but not when I want to make a selection from a UITableView that is embedded in the same view. (The text fields are located outside this table view).
Essentially each table view cell represents a pre created specific time that is chosen to match the text entered into the text fields then passed along all together to another view.
Any Idea how I can get the UITableView to still recognize the selection of cell when tapped while resigning first responder of the text fields?
I have tried adding a gestureRecognizer function but as I am new to Swift(and an amateur coder) I am not exaclty sure how it works. Any help would be greatly appreciated!
Thanks.

try to add tap.cancelsTouchesInView = false
It means touches are delivered to a view when a gesture is recognized.

Related

UITableView cancels UITapGesture

uitableviewdidselect cancel outs tap gesture action
there is an UIImageView in cell.contentView and there is a tap gesture to enlarge the image the control is not going to the Tap Gesture action its passing to the tableview didselect delegate ? I am using UITableView class for my table already did userInteractionEnabled=YES & cancelsTouchesInView = NO
Make sure you set
tapGestureRecognizer.cancelsTouchesInView = NO;
It won't work because table view can't take two user interactions at a time. First it will give priority to didSelectRowAtIndexPath. You need to disable user interaction on cells. So that tap gesture will be called. Make sure that user interaction enabled for imageView.

Is it possible to disable didSelectRowAtIndexPath in a part of row in UITableView?

I have a UITablaView in my Objective C application. I have the custom cells with a label and a UIImageView. I want to disable a part of the rows, to disable didSelectRowAtIndexPath when users click on this row's part.
I want this:
Is it possible?
Here is the simple and the most elegant solution that I can think off.
I believe you must be having a CustomCell, which holds the IBOutlet to imageView on the left side :) You can make use of hitTest method to solve your problem :)
In your CustomCell lets assume it to be MyTestCell class write this,
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if self.myImageView.frame.contains(point) {
return nil
}
return super.hitTest(point, with: event)
}
Where myImageView is the IBOulet of imageView on the left hand side of your cell :)
All am doing is checking where did user tap, if the touch point is within the frame of cells imageView you return nil as the view. When you return nil touch event stops propagating to its parent views and finally will never reach cell hence didSelectRowAtIndexPath never called,
On the other hand you should handover touch to the next view and you do it simply by calling same method on its super iOS will eventually trace it back to cell and triggers didSelectRowAtIndexPath
Hope it helps :)
You can do a simple trick (without the need of writing code) to solve this issue, by adding a button that covers the part that you want to disable the selection of it. Obviously, the button should not have any text or background color (it should be clear color), also make sure to add suitable constraints for making sure that is covered the wanted part of the cell.
So when tapping on the button, nothing should happen and didselectRow should not get called because the actual touching event should be referred to the button, not to the row.
Hope this helped.
This is very simple trick,
Add a button on profile image part, means on red part as shown in picture (provided by you). And don't do on click on button click.
Happy Coding!!!!
Simply put the button over Green area and set tag for each button. Onclick you can perform your functionality using tag. Like this
inside
func tableView(tableView: UITableView,cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let obj: AnyObject = self.dataList.objectAtIndex(indexPath.row);
cell?.populateCellWithData(obj, indexPath: indexPath)
cell?.destinationLabel.userInteractionEnabled = true
let destRecognizer : UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "DestLabelTapped:")
destRecognizer.numberOfTapsRequired = 1
destRecognizer.delegate = self
cell?.destinationLabel.addGestureRecognizer(destRecognizer)
}
and in DestLabelTapped you can peform your functionlity
Another way
Just set two Tableview and scroll them side by side and one table is selectable and another is not. (don't do this)
In my understanding the tricks with buttons and other UIElements that are covering the content are not the right way to solve the target. As you will need extra manipulations with them in Storyboard, if you will need to make dynamically content, if you will work with constraints and many more situations where you will need to control your content and + the artificial cover. There are few things to do:
Set UITableView selection to No Selection
Put the second part that you want to be active in UIView. This UIView will be the content container.
Add UITapGestureRecognizer to UIView
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(selectCellAction:)];
Add IBAction where you could do all you need.
- (IBAction)selectCellAction:(id)sender
{
// do what you need
}
And thats all.
You may simply do change the image view width constraints to 0. Where you want to action is performed. As for example:
1) If you use a button that cover the image.
2) If you take a navigation bar then you there take a button and perform the action.
hope this will help.

Calling endEditing on a UIView

I have a tableView with two UITextViews. The user can add as many cells as they want by tapping on a "+" button. The tableView starts out with one row (cell). Lets say the user adds some information to the two textViews and then taps the plus button and scrolls to get to it. I call this function to dismiss the keyboard when a user scrolls so it isn't in the way:
override func scrollViewDidScroll(scrollView: UIScrollView) {
self.view.endEditing(true)
}
Now, the keyboard disappears and the user goes to tap on the second row's text field. The tableView jumps up (I think to accommodate the keyboard), but the textField can't be edited (no cursor and keyboard doesn't appear). If I go back up to the first row (row 0), the keyboard appears and I can edit the textView. Why is this happening?
There is a property on scrollView subclasses (e.g TableViews)
tableView.keyboardDismissMode = .OnDrag
Once the user begins a descending drag it dismisses the keyboard
scrollViewDidScroll calls everytime the tableview moves, so when "The tableView jumps up (I think to accommodate the keyboard)" it also calls and close the keyboard. You should add there some confines or put endEditing code in the other place.

GestureRecognizer doesn't work on TableView

I'm trying to find a way to hide the keyboard as soon as the user taps elsewhere on the screen after filtering the content of my tableview.
But somehow when I add an UITapGestureRecognizer my TableView freezes and it's impossible to go further into the application.
Here's what I do :
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "dismissKeyboard")
self.view.addGestureRecognizer(tap)
func dismissKeyboard() {
view.endEditing(true)
}
I've tried this on a Blank ViewController with a TextField and it works. What am I missing? Is there a specific way to add GestureRecognizer to table views? Because as soon I add the Gesture it breaks everything. I also tried using resignFirstResponder with the same results.
Any advice? Thanks!
Try setting the cancelsTouchesInView variable to false. This defaults to true, by setting it to false you allow the touches to be responded to by your gesture and then pass through your gesture back down to the view so the tableView can respond as well.
tap.cancelsTouchesInView = false
Documentation on Apple
Discussion Excerpt from Docs:
When this property is true (the default) and the receiver recognizes its gesture, the touches of that gesture that are pending are not delivered to the view and previously delivered touches are cancelled through a touchesCancelled:withEvent: message sent to the view. If a gesture recognizer doesn’t recognize its gesture or if the value of this property is false, the view receives all touches in the multi-touch sequence.

Prevent TableView from scrolling when sidebar is active

I have a sidebar in an UITableView which will display after a long press on a cell. The sidebar has some custom buttons for more functionality.
If the user tab on the UITableView, I will check for the location of the point. If it is outside of the sidebar, then I will close it.
The problem here is, if the user try to scroll (its about 100 rows here) the sidebar stays on the exact place. So my goal is to prevent the user from scrolling on the table as long the sideview is present. (I will also highlight the selected row later.)
I created a UIGestureRecognizer:
tapGesture = UITapGestureRecognizer(target: self, action: "handleTap:")
view.addGestureRecognizer(tapGesture!)
And check the location:
func handleTap(recognizer: UITapGestureRecognizer){
let location = recognizer.locationInView(view)
if !CGRectContainsPoint(contentView.frame, location){
// dismiss
}
I have a delegate which shows me if the sideview is present, but if I try to set:
tableView.userInteractionEnabled = false
I am unable to click on the sideview, so all user interactions are disabled.
Is there a way to disable only scrolling?
So simple just write this
tableView.scrollEnabled = NO;

Resources