Redrawing UITableViewCell when entering/exiting edit mode - iphone

I have a table view in which the cells are built differently depending on whether the table is editing or not. Specifically, the selection style is none when in edit mode and blue when not in edit mode.
When I transition from one to the other, I noticed that some of the cells are not updated. A quick bit of logging tells me that even though the cells' appearance changes quite drastically (accessory views are added/removed correctly for example) the table view does not refresh the selection style (nor for that matter the text).
What is going on here? Are only some attributes of the cell updated when setEditing is called? Presumably only those with a specific method allowing allocation of a separate view style (for example the EditingAccessoryType)? I guess I would benefit from a EditingSelectionStyle.
How should I resolve it? By customizing setEditing to change the selectionStyle for each cell? I'm not even sure how I would iterate through the table view to do this. reloadData isn't an option because of some animation that I am using.

I found that customizing setEditing: to iterate through the visible cells and setting the selectionStyle for each to work ok.
- (void)setEditing:(BOOL)editing animated:(BOOL)animated{
[super setEditing:editing animated:animated];
for (UITableViewCell *cell in [self.tableView visibleCells]) {
NSIndexPath *path = [self.tableView indexPathForCell:cell];
cell.selectionStyle = (self.editing && (path.row > 1 || path.section == 0)) ? UITableViewCellSelectionStyleNone : UITableViewCellSelectionStyleBlue;
}
}

If you look at the UITableViewDelegate documentation you will see a that there are five methods to customize the editing behavior. There is also the method
- (BOOL)tableView:(UITableView *)tableView
canEditRowAtIndexPath:(NSIndexPath *)indexPath
in the UITableViewDataSource documentation that will be called on each cell before you go into editing mode. The same is true for
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
that will get called for all cells that are editable. If you want to change the way the cells look you could do it in either of these. (Not implementing canEditRow.. assumes all rows are editable.)
Also note that there may be other ways to enter editing mode such as swiping on a cell, in which case
- (void)tableView:(UITableView *)tableView
willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
will be called for the cell that you swiped on:
When entering this "swipe to delete" editing mode, the table view sends a tableView:willBeginEditingRowAtIndexPath: message to the delegate to allow it to adjust its user interface.

This works on Swift 2.3, just overwriting the setEditing method in your custom cell subclass:
class MyCell: UITableViewCell {
override func setEditing(editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
//Place your code here...
}
}

Related

Which method will be called when we hold the UITableViewCell

When we select UITableViewCell than - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath called.
But which method will be called if we hold the UITebleViewCell. Guys my problem is that I have created a tableview which contain large cell and in that cell I am setting various view an view's background color.
When I select the cell, the background color of my cell will be gone. I have solved this problem by setting view background color again in didSelectRowAtIndexPath method like this.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
UIView *vLineview=[selectedCell viewWithTag:1];
vLineview.backgroundColor = [UIColor colorWithRed:(89/255.0) green:(89/255.0) blue:(89/255.0) alpha:1];
}
This done the trick and my view background color will displayed but when I hold the UITableViewCell than it will gone again.
How can I solve this? Do I have to and gesture recognizer to detect long touch and implement my view background method in it? Or there is any other method available for that.
Try with set cell selection style none like this in cellForRowAtIndexPath
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
You can subclass UITableViewCell and override this method:
- (void) setSelected: (BOOL) selected
animated: (BOOL) animated
{
[super setSelected: selected
animated: animated];
// Configure the view for the selected state
}
Is this an issue with the UITableViewCell remaining selected after you tap on the row?
If row selection is not required, make sure you call deselectRowAtIndexPath:animated at the end of your tableView:didSelectRowAtIndexPath method.
[tableView deselectRowAtIndexPath:indexPath animated:YES];
Pleasese see method named -(void)beginUpdates
Call this method if you want subsequent insertions, deletion, and selection operations (for example, cellForRowAtIndexPath: and indexPathsForVisibleRows) to be animated simultaneously.
for more detail visit apple documentation in below link
UITableView Class Refrence
Also try [cell setSelectionStyle:UITableViewCellSelectionStyleNone];

How can I animate the dismissal of a UITableView swipe-to-delete button?

As is done in the iPhone Mail app, I would like have the "Delete" button which appears on swiping an editable table cell from right to left to animate when it is dismissed (by way of tapping elsewhere than the Delete button on the UITableViewCell). Instead, my Delete button immediately disappears when it is dismissed.
To invoke the Delete button on swiping a table cell in the first place, I have added (to the class which is the UITableViewDataSource and UITableViewDelegate for the UITableView in question):
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
//add code here for when you hit delete
}
}
Is there something I might add to this which will handle the animation of the Delete button when it is dismissed? Thank you!
I had the same problem, just now found out that there is some problem when we have empty cell.textLabel.text. Try add in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath:
{
{...} // omitted code
cell.textLabel.text = #"whatever";
cell.textLabel.hidden = YES;
}
With this swipe button dismiss proper, but WHY?
PS: tested with custom cells and built i.n
You should not need to animate the dismissal manually, it works the same way as invoking it so not sure why it is behaving differently in your app.
Are you using custom cells by any chance? As a thought for you to try, change the shouldIndentWhileEditingRowAtIndexPath: method to return NO and see if it changes anything. The only thing I can think of is that your content indentation is interfering with the delete button area in a way that the animation can't be performed or is not behaving as it should.
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath {
return NO;
}
I've just ran into this issue as well. I have a series of tableViews and I noticed that some of them have the proper dismissal fade and others don't.
It seems the difference is a UITableViewCellAccessory. If this is set to anything other than UITableViewCellAccessoryNone then you get the proper animation. I think this might be a bug. Can anyone else confirm this behavior?
**> //MARK:-Tableview delete to left in swift without any tag By using Button Action**
let point = sender.convert(CGPoint.zero, to: tableView)
guard let indexpath = tableView.indexPathForRow(at: point) else {return}
stringArr.remove(at: indexpath.row)
tableView.beginUpdates()
tableView.deleteRows(at: [IndexPath(row: indexpath.row, section: 0)], with: .left)
tableView.endUpdates()

Left delete icons not appearing while UITableview edit mode

I have a core data/ uitableview based app. Actually 80% of the code so far is equal to the Apple Sample app CoreDataRecipes. My problem is that when I enter the edit mode (by pushing the edit button), there are no "delete badges" on the left side of the rows. Bumper.
The differences in code with CoreDataRecipes:
I have custom UITabelview cell with
a nib file instead of code only.
My Tableview is an Outlet inside my class view. So my class
RecipeListTableViewController is an
UIViewController with Tableview delegates instead of a UITableViewController
What I tried:
The Tableview works fine. There are no linking or delegate issues
I checked if the table actually
enters the edit mode. It does. You
can see that because the "Add" button
is disabled.
I checked if the editingstyle is ok. It should be by default but to make sure I added:
(UITableViewCellEditingStyle)tableView:(UITableView*)tableVieweditingStyleForRowAtIndexPath(NSIndexPath*)indexPath {return UITableViewCellEditingStyleDelete;}
I checked if the delete icons where not behind my cellview. There are not. I now think that the cell behaviour of moving to the right is handled by iOS.
When I swipe the cell, the right delete button appears and works as it should
I tried to build the behaviour my self with a layoutSubviews. Nothing changed when entering the edit mode. But when I swipe, now I see my subview in one row:
Anyone any ideas? It must be something simple.
Make sure that
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
If this is not set to return YES then the badges will not be enabled. The default is set to return NO
I think you have not added the line
tableView.editing=YES on clicking the Edit button
Try by setting it!
Since yours is a UIViewController, the tableview doesnt get the setEditing call. Just add:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
[self.tv setEditing:editing animated:YES];
}
Make sure you have setup the outlet/ delegate/ datasource
then these:
-(void)editButtonTapped
{
[self.tableView setEditing:YES animated:YES];
}
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleDelete;
}

editingStyleForRowAtIndexPath Scrolling problem

I am facing a very strange problem with editingStyleForRowAtIndexPath method. I am planing to change the appearance of editable cells. It was working fine, but when i scroll the table i am not getting the table cell pointer in the editingStyleForRowAtIndexPath delegate method. So the new cells does not get the custom appearance.
I am using this -
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
// get tablviewcell pointer
UITableViewCell* pCell = [tableView cellForRowAtIndexPath:indexPath]; // <- not getting the pointer when scrolling the table and new cells come up
//Changin cell appearance here ...
}
Thanks in advance!
I think the table view may call this method before it assigns a cell to the given index path. A more reliable way to customize table view cells would be to override -tableView:willDisplayCell:forRowAtIndexPath:. You can test the cell's editingStyle property there and act accordingly.

How do I disable selectRowAtIndexPath when subview is visible

I am writing a "tweetie 2" like swipe functionality, but have run into what I hope is the last stumbling block.
When a user swipes across a table row the "controls" view animates as expected, but when the row is selectd, didSelectRowAtIndexPath is fired off. The desired result is for when the "controls" view is visible to disable the didSelectRowAtIndexPath method or for a lack of a better phrase...stop the responder chain for continuing past the "controls" view.
The uitouch delegate methods are used/being called in the custom uitablviewcell.
What about setting/unsetting the value of allowsSelection in UITableView as needed?
A bit of logic should do the job here. Let's say you add this property to your UITableViewController subclass:
NSIndexPath *indexPathForCellInUtilityMode;
When the user triggers the cell's utility view, your cell does this:
NSIndexPath *cellIndexPath = [parentViewController.tableView indexPathForCell:self];
parentViewController.indexPathForCellInUtilityMode = cellIndexPath;
Then:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if ([indexPath compare:indexPathForCellInUtilityMode] != NSOrderedSame) {
//Do whatever you're normally doing in this method.
}
So you'll disable selection for the affected cell while still allowing the user to interact with other visible cells.