I have a custom UITableViewCell. I have a UIImageView in the Cell and when I select the Image it changes like it should but the cell is also selected which I do not want. So my question is how can I make a certain area of my cell not selectable?
I tried overriding the touchesBegan or touchesEnded but that did not work because then I cannot select the cells at all.
if you only want to not show the selection color, use:
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if you have something triggered by a cell tap, it will still happen, so if you want to disabled that also you need to take care of that in:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
or if it triggers a segue, in:
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
In cellForRowAtIndexPath you can set userInteractionEnabled to false:
cell.userInteractionEnabled = NO;
Related
I have my table view that displays cells with some content and a custom accessory button.
When i tap a cell, a 5s work is launched. I don't want the user to tap a cell while the background work is not finished, so i do:
self.tableView.allowsSelection = NO;
It works fine, the user can't tap a cell.
I used to do:
self.tableView.userInteractionEnabled = NO;
But i want to scroll my table view while working in background. The issue is that i also can tap on the cell's accessory button.
How to avoid that not losing the table view scroll?
I could do:
- (void)didSelectAccessoryButton:(UIButton *)pButton onEvent:(id)event{
if(self.tableView.allowsSelection){
//Usual accessory button code
}
}
But the accessory button highlight would still be there, meaning at some point i'd need to do in cellForRowAtIndexPath:
[accessoryButton setShowsTouchWhenHighlighted:NO];
I just wish the allowsSelection = NO avoids the tap on accessory button too... So what's the better way ?
The best way i've found is to combine this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
//...
tableView.allowsSelection = NO;
[tableView reloadData];
//...
}
with this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//...
accessoryButton.userInteractionEnabled = tableView.allowsSelection;
//or cell.accessoryView.userInteractionEnabled = tableView.allowsSelection;
//
}
And when the job is done, self.tableView.allowsSelection = YES;.
What bothers me with this solution is the need to check inside cellForRowAtIndexPath as to do so i also need to reload data; but in the end it's just 3 lines.
Thank you #virus for the simple "userInteractionEnabled to accessoryButton" idea.
I want to disable cell interaction. In my function:
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
I added
Cell.userInteractionEnabled = NO;
And cell interaction is disabled, but I want to leave active button (ButtonLabel).
Cell.userInteractionEnabled = NO;
Cell.ButtonLabel.userInteractionEnabled = YES;
The above code does not work. It is strange, because inversly is ok:
Cell.userInteractionEnabled = YES;
Cell.ButtonLabel.userInteractionEnabled = NO;
Button is disabled but cell no.
How to make my button active while cell is disabled ?
When you set userInteractionEnabled to NO on any instance of UIView (or its subclasses), it automatically disables user interaction on all its subviews. This is exactly the behaviour that you described.
I think what you want to do is to disable selection on a UITableViewCell. There are several ways to do it:
If you want to prevent selection on all cells altogether, you can
just set tableView.allowsSelection to NO.
If you want to prevent selection on certain cells only, do Cell.selectionStyle = UITableViewCellSelectionStyleNone;
And you can also override - (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath; and return nil for cells that shouldn't trigger selection action (but this alone won't prevent the selection highlight from appearing.)
According to your comment, you want do disable push connection for specific cell. What you can do is check in shoudlPerformSegueWithIdentifier if that cell should perform.
You need to save which was the cell touched, and then:
-(BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
if (/*check if the selected cell should perform the segue*/) {
return YES;
}
return NO;
}
If you disable interaction on the cell this will affect all cell elements. What you want to do instead is set the cell to UITableViewCellSelectionStyleNone
This will work
[Cell setSelectionStyle:UITableViewCellSelectionStyleNone];
Cell.ButtonLabel.userInteractionEnabled = YES;
I've a tableView with some cells. Each cell also contains a button. When the user clicks the button, the cell should be unclickable, but not the button. So when the user clicks on the button of a cell which is not clickable, this cell should be clickable again.
I tried:
cell.userInteractionEnabled = NO;
...but then the button wasn't clickable anymore.
Thanks to your effort in advance.
EDIT
I mean: When I click on a cell a new view opens. But I want, that no action happens, when the cell is not "clickable".
Unclickable in which way? If you just want the cell to not be selectable, you are probably seeking for this:
cell.selectionStyle = UITableViewCellSelectionStyleNone;
If you want to prevent your code to be executed when the selection is disabled, just check for the selection property inside your didSelectRowAtIndexPath:method. Something like this:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.selectionStyle != UITableViewCellSelectionStyleNone) {
//(your code opening a new view)
}
}
Remember, you still have to play with this property, setting to UITableViewCellSelectionStyleNone when you don't want the cell to be selectable, and setting back to UITableViewCellSelectionStyleBlue (or UITableViewCellSelectionStyleGray) when you want it to be selectable again.
Swift version:
cell.selectionStyle = .none
Remove selection by setting UITableViewCellSelectionStyleNone as the selectionStyle.
cell.selectionStyle = UITableViewCellSelectionStyleNone;
And do nothing in -tableView:didSelectRowAtIndexPath:
You can be selective in that delegate method for example if only the first row in the first section has the button and should do nothing :
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSIndexPath *indexPathForDisabledCell = [NSIndexPath indexPathForRow:0
inSection:0];
if([indexPath compare:indexPathForDisabledCell] != NSOrderedSame) {
//Do whatever you do with other cells
}
}
This can also be done through Interface Builder using User Defined Runtime Attributes on the TableViewCell:
Key Path | Type | Value
selectionStyle | Number | 0
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewCell_Class/#//apple_ref/c/tdef/UITableViewCellStyle
In my TableView i load cells based on a xib file. The cell has a imageView in the background. How to change the image when user holds finger on a row? I dont meen didSelectRowAtIndexPath, cause it means the user tapped the row.
Implement the - (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated method on your cell subclass and change the image there based on the value of the highlighted parameter.
Hope this help
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath{
// update your image here
return YES;
}
I have a tableview, where when the user selects the cell it will set the accessorytype to UITableViewCellAccessoryCheckmark.
Now when I navigate to the previous screen, then go forward to this tableview, my cells remains checked.
Is there a way to uncheck all of them? I guess basically set all of them to UITableViewCellAccessoryNone.
I tried using reloadData, when the view appear, but that doesn't seem to trigger the cellForRowAtIndexPath (this is where my logic is to set the accessorytype of the cells)
I think this may do what you want. I assume you want to uncheck all the cells as part of responding to tableView:didSelectRowAtIndexPath: but you could insert this code anywhere:
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Uncheck any visible, checked cells.
NSArray *visibleCells = [tableView visibleCells];
for (UITableViewCell *cell in visibleCells) {
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
// Now do whatever else you want in response to a row being selected.
}
You should set the accessorytype in tableView:willDisplayCell:forRowAtIndexPath: instead of cellForRowAtIndexPath so that it is updated whenever it is displayed (and not just when created).
There is a tableview method called clearsselectiononviewwillappear that you might have accidentally overwritten. The default behavior should be YES. Check out Apple's doc
on UITab