If you notice in the iPad contacts app when you tap on the "+" edit icon to add a new address, the cell does not expand to the left when the icon disappears (see 1st screen capture below). I am trying to do something similar but am having no luck (see 2nd screen capture below). I tried using the solution suggested here but didn't work.
For the record I am not trying to replicate the actual contacts app or integrate with contacts. We're working on something unrelated and my designer just wants to follow this pattern so doing some POC work to see what I can do.
EDIT - Another question, to verify my thinking, is that in the contacts app here what's happening is when the "+" icon is tapped, this cell is set to not editing any more, these text fields are added to the cell, the label changed, and then reloadData is called, right?
EDIT - Thanks for the suggestion Tim, I'm almost there! I had actually worked out 1/2 of it but then was running into the issue that the "+" icon was not animating out, just abruptly disappearing. So I added the reloadRows... call to commitEditingStyle but now the entire cell disappears. Here is my code:
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCellEditingStyle editingStyle = UITableViewCellEditingStyleNone;
if (self.showEditingIcon) {
editingStyle = UITableViewCellEditingStyleInsert;
self.showEditingIcon = NO;
}
return editingStyle;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
// tableView.editing = NO;
// tableView.editing = YES;
[self.tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
You can see from my commented-out lines what I had originally, which was working but as I said, was not animating - the "+" button was just abruptly disappearing. If I tried to call [tableView setEditing:NO animated:YES] it would not work. When I tried to put these calls within a UIView animation block it did not look good - could see cell temporarily shift to left and back. However now with the reload call the cell disappears completely. At the moment I'm not making any changes to my cell (for example I'm not adding text fields, etc...) because I just want to make the "+" button animating out without making the cell expand the left work on the first iteration.
Any help greatly appreciated. Thanks.
The trick is to always be in editing mode such that the cell indention remains constant. When the cell is loaded, you decide what state it is in and return the appropriate editing style, either the "insert" style or "none":
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
BOOL shouldShowInsertButton = ...;//check internal state for cell
return shouldShowInsertButton ? UITableViewCellEditingStyleInsert : UITableViewCellEditingStyleNone;
}
Then when the edit button is tapped, you update your internal state and reload the cell:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
...;//update internal state for cell
[self.tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
EDIT
Here's a working sample project.
Related
It's really odd. :(
I am trying to implement swipe to delete in tableview. For this below is what I have.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"commitEditingStyle===%#", editingStyle);
if (editingStyle == UITableViewCellEditingStyleDelete) {
//add code here for when you hit delete
NSLog(#"now delete this cell");
}
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleDelete;
}
Still when I swipe, swipe is done, but I can't see Delete button.
Any idea what is going on?
Edit 1
Something more weird now.
When I say mainTableView.editing = YES; in viewDidLoad, I have below.
Why delete option is appearing on the left side?
Also with editing option, still it appear same as first image.
Edit 2
// table view delegates
- (int)numberOfSectionsInTableView:(UITableView *) tableView {
return 1;
}
- (int) tableView:(UITableView *) tableView numberOfRowsInSection:(NSInteger)section {
return actualProductsArray.count;
}
-(UITableViewCell *) tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MainCell"];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"MainCell"];
// created label and added into cell...
cell.backgroundColor = [UIColor clearColor];
cell.contentView.backgroundColor = [UIColor clearColor];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
Though this is not real answer, but below was error.
While defining size of tableview, I had defined its width as 1080 against 320 and hence I was not able to see delete button as it was way ahead of screen.
I had the same problem and it wasn't related to the width of the table or not having canEditRowAtIndexPath. I noticed the right nav bar button (Edit) would flash when I swiped left. The bug I found in my code was that I was calling tableView.reloadData() inside the setEditing method.
override func setEditing(editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
tableView.reloadData()
}
When I deleted the tableView.reloadData() line, the Delete button showed up just as expected. The reason I was doing the reloadData was because in Edit mode, I added an Insert line at the bottom of the table with an editingStyleForRowAtIndexPath = .Insert
You have to try Tableview.editing=YES in ViewDidload
I am only using the below line for swipe to delete in my code it works perfectly fine for me.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
// Delete the row from the data source
//[self.tblinboxmsg deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
Hope it helps you too...
I think you add the label directly on cell and not on cell.contentView.
If you provide the code here
// created label and added into cell...
We can help you more.
tableView.editing = true
has the behaviour like you have on image Edit 1. (Buttons are on left side)
But the buttons are on content, which should not. Because you are adding labels on cell directly
please add the labels in contentView and try again
I know this has been solved for over a year now but for some people that might encounter this problem, This might be just a constraint issue.That is how I solved mine.
Can't believe I've been trying to solve this problem for days, literally!, because I thought it was somewhere in my code implementation because I transitioned from UITableViewController to UITableView on a UIViewController. I just copied the UITableViewCell from the original UITableViewController and the code works well from the original UITableViewController implementation.
#Fahim Parkar first screenshot is pretty much the same scenario as mine. Slide and not showing delete. I think this means that canEditRowAtIndexPath is already implemented. His answer I believed is set in code but it led me to try out to check my constraints and finally fixed it
I have a simple UITableView
I'm doing my first Edit implementation, to add Delete functionality. Most of this stuff is the default apparently. Pretty much the only method I added to my Controller is
- (void) tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
{
Program *victim = Site.current.sortedPrograms[indexPath.row];
[Site.current removeProgram: victim];
[self.tableView
deleteRowsAtIndexPaths: #[indexPath]
withRowAnimation:UITableViewRowAnimationAutomatic];
}
When I hit the Edit button, I see
which is good. But When I hit the minus button on one with a shorter title, I see the following
The title is completely scrolled out of site! Similarly, if I use the iOS 7 swipe left gesture, even on a longer title, the title is scrolled out of view:
The code I use to create the cell is pretty simple:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ProgramCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
Program *program = Site.current.sortedPrograms[indexPath.row];
cell.textLabel.text = program.name;
cell.detailTextLabel.text = [program.script prettyCycleDuration];
return cell;
}
This isn't what I want my users to see. I would rather see it scroll the title only if necessary, so that context (not whitespace) associates with the delete button. I am just using a stock UITableViewCell (not a subclass), and I'm setting the 'style' to Subtitle. I've looked at the delegate methods, and a book I have, but I don't see anything that shows how to deal with this. Is there a way? Will I need to do my own Cell subclass and handle the states more explicitly? Or is there something else I can do?
Update
Even after converting to a custom subclass, with constraint based layouts for my cell, it still slides the whole view over, rather than compress it.
I am able to make the red minus button appear on each of my UITableViewCells with the following calls:
[self.tableview setEditing:YES];
and
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleDelete;
}
Now, the red minus buttons appear to the left of the UITableViewCells. However, I can't interact with them via a simple tap (only if I swipe from the red minus to the right).
I want the "Delete" button to appear when I tap on the "Red Minus" button, not just when I swipe.
Why isn't my "Red Minus" button listening to a tap gesture?
EDIT: Here's a screenshot of what my UITableViewCells look like:
Figured it out. I had a gesture recognizer getting in the way (dismisses the keyboard when you click outside of the searchbar).
once I removed that everything worked great!
Have you implemented the commitEditingStyle tableViewDelegate method?
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
}
I have a main window which has two UITableViewControllers. On selecting the cell in first tableViewController (left pane), the tableViewContainer on the rightside gets populated. In the Voice over mode, I want that when the cell in the first tableViewController is selected, the first cell in the secondViewController gets focus so that the flick order starts from there. Please note that I have already tried the following two approaches:
1) Making the first cell of the second view controller, the firstResponder.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *outCell =(UITableCellView*) [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (indexPath.row == 0)
{
[outCell becomeFirstResponder];
}
}
2) I also tried posting the layout changed notification given the cell as the first accessibility item.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *outCell =(UITableCellView*) [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (indexPath.row == 0)
{
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, outCell);
}
}
None of the above approaches worked. Any idea what else can I try or what is wrong with the above approaches?
Please note that: I have read the View controller’s documentation (https://developer.apple.com/LIBRARY/IOS/#featuredarticles/ViewControllerPGforiPhoneOS/Accessibility/AccessibilityfromtheViewControllersPerspective.html - Moving the VoiceOver Cursor to a Specific Element). Tried posting LayoutChanged notifications as well as ScreenChangedNotifications in my sample as well as tried with the sample code (ListAdder - http://developer.apple.com/library/ios/#samplecode/ListAdder/Introduction/Intro.html, which also uses the NavigationController as we does), but the above did not work even with the sample.
Any idea why?
I solved this issue by posting the screen changed notification. The second parameter to that call is the table view's view that you want to select the first cell of.
UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, [[self nextTableViewController] view];
I have a tableview that loads with isEditing = YES. This is a bit of a hack (but a reasonable one I think) because I want one of my cells to always display the 'add' icon. I don't want the other cells to include the 'delete' icon so I am returning UITableViewCellEditingStyleNone for these.
However, I would still like to provide swipe to delete functionality on those cells. Since the tableview is already in edit mode, is this going to be possible?
If not, I will probably achieve the 'add' icon using the cells imageView, but this seems hacky too.
Edit: Similar question found here:
swipe to delete when already in edit mode
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[myArray removeObjectFromindex];
}
[mytableview reloadData];
}