UITableViewCell and UITextField with user interaction disabled doesn't call didSelectRow - ios

My cell has a UITextField (bound to all the edges) with isUserInteractionEnabled on false. So I expect that when I click the cell the didSelectRowAt is called.
Nowm this never happens. It doesn't call the didSelectRowAt function.
Is there any way to find out who is consuming my event? Also in the view debugger, I don't see any views on top of it.

Make sure you implemented UITableViewDelegate.
Make sure you have not added UITapGestureRecognizer anywhere in your
view.

Make sure your VC is delegate of UITableView
Make sure your tableView selection is not "No Selection"
And final, try to use
textfield.isEnable = false
instead of
textfield.isUserInteractionEnable = false

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.

How to callback a function in tableView's Class from tableViewCell's Class

I'm having a TableView. In that tableView, I custom it's cells
like this
In this cell I have 2 part. An Image and an TextField.
It's look like facebook's post status. When I click to Image, I want to open a new ViewController and the same for TextField
But I have a problem that I can't call segue from my cell's class file.
Are there any way that I can call a function in TableViewController's class from TableViewCell's class ?
I know that I can use delegate but I don't like this way a lot, because if I do this way I have to set a lot of delegate in my project.
Are there any better way to present a new ViewController directly from TableViewCell's class
Using a delegate is a very good way to solve your problem.
If you don't like that solution then you could design a table view cell that has a closure property set by the view controller, and invokes that closure when the button is pressed.
EDIT:
Another alternative is to leave the button action empty in your custom cell, but still connect up outlets to the buttons.
Then in your cellForRow(at:) method, install an IBAction that has your view controller as the target. (Credit to #SoanSani, who's answer is below)
In that IBAction method, you can use the coordinates of the button to figure out the indexPath of the cell hat contains the button that was tapped.
I've created an extension to UITableView that lets you figure out the cell that contains any view. The code is below:
import UIKit
public extension UITableView {
/**
This method returns the indexPath of the cell that contains the specified view
- Parameter view: The view to find.
- Returns: The indexPath of the cell containing the view, or nil if it can't be found
*/
func indexPathForView(_ view: UIView) -> IndexPath? {
let origin = view.bounds.origin
let viewOrigin = self.convert(origin, from: view)
let indexPath = self.indexPathForRow(at: viewOrigin)
return indexPath
}
}
You can use delegates, but if you dont want to use delegates
while setting up the cell add target to your button tableViewController class and then you can receive all events in tableview class rather than cell class.
But this would require to add tags which you can use to differentiate which button in cell was clicked
Objective C Code
[OkBtn addTarget:self action:#selector(okButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
Swift Code
OkBtn.addTarget(self, action: #selector(ViewController.okButtonTapped), for: .TouchUpInside)

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.

Custom UITableViewCell button click

In a UIViewController there is a UITableView which consists custom UITableViewCell with a UIButton.
When the user clicks the button (in the custom UITableViewCell), I want to display a message in the hosting UIViewController - what is the right way to achieve that? How should I notify the UIViewController that the button was clicked?
You should use delegation to tell the UIViewController that something happened in the cell.
I'm not exactly sure what kind of message you are referring to but if you mean a you want to show a popup just create a UIAlertView and show it when the button is clicked in the cell.
However, if you mean change a UIlabel text or whatever as a message on the ViewController you can always pass whatever you need to change into the TableView and Cell or the UIViewController itself into it.
I usually create a method on the custom cells class and pass it whatever I need into the custom TableView's constructor. Then in the TableView's GetCell() method pass whatever I need to change into that method I created on the cell and save it as a variable on the cell.
If you've initiated your UITableViewCell, and added a button to the cell, you can use a Delegate when the button is clicked, something like this:
UIButton button = new UIButton (cell.Bounds.X, cell.Bounds.y, cell.Bounds.Width, cell.Bounds.Height);
button.TouchUpInside += (object sender, EventArgs e) =>
{
label.text = "Blablabla";
};
Where the label is, is up to you. I hope this helps, good luck!

How to handle multi-touch in UITableViewCell with buttons?

I have custom table view cells that each have 3 buttons. Selecting a row in the table pushes another view controller; pressing one of the buttons shows a modal view.
If, with two fingers, I select a row, and press a button, both the controller gets pushed and the modal view appears . I've tried setting a flag in the buttons' TouchDown event and returning nil in
tableView: willSelectRowAtIndexPath:
if the flag is true, but the flags gets set to false in the buttons' TouchUpInside event handler, so the tableview: didSelectRowAtIndexPath: still gets called.
How can I solve this issue ?
In your button's touch down method, set the UITableView's allowsSelection property to NO. Then in the touch up (both inside and outside) handler set it back to YES.
It helps
cell.contentView.exclusiveTouch = YES;
cell.exclusiveTouch = YES;
setting exclusiveTouch to custom UITableViewCell

Resources