Remove left space from UITableViewCell on setEdit:YES - ios

I have a tableView with some questions that a user can reorder so I have set the property setEditing to YES
[questionTableView setEditing:YES animated:YES];
also I donot want my user to delete any of the rows neither add so I have returned the UITableViewEdtitingStyle to UITableViewCellEditingStyleNone; in its delegate function.
However, the cell has got a lot of space at the left which I need to remove. How can i do that ?

Related

How to add a subview to a TableViewCell?

I need to add a subview to TableViewCell when the button in TableViewCell is clicked it should show another tableview as a subview and height of the tableview should be dynamic according to number of cell.
How can I do this?
Above screenshot is taken from a very popular shopping app and I need to do the same in my project.
You can easily achieve this using simple UITableView. For that you need to set all your main categories as your UITableview section and respected sub-categories can be added to respective rowOfSection.
You can use just one table view with UITableViewStyleGrouped style, and set "Men","Women","Kids & Baby" as TableView sections header, keep an boolean value to determine the result of "numberOfRowsInSection:" of each section and reload tableview.
See the below link at github:
https://github.com/OliverLetterer/SLExpandableTableView
This contains the Expandable TableView, which you required. You have to implement SLExpandableTableViewDelegate and SLExpandableTableViewDatasource which contains different method, in which you have to provide inner tableview as well.
Hope this helps you.
You need to do some work on your own I can give the directions that'll give you a way from my point of view :-
Make a Custom cell which you want to expand.
While designing the cell make its height in storyboard like 200 or so according to your need and add all the elements those you want to see when the cell is expanded.
You'll need two delegate methods first -didSelectItemAtIndexPath and second HeightForRowAtIndexPath at index path.
First You need to make sure the user taps on the button or cell that you want to expand , and to achieve that you need to call didSelectItemAtIndexPath.
Once you get your cell Position, in HeightForRowAtIndexPath check the indexpath is equal to your cell's indexpath,if yes then return the exact height(ie:200) of your cell otherwise return the default(ie:70) height of you cell.
Note : In didSelectItemAtIndexPath you need to call to method to update the current cell
[self.tableView beginUpdates];
[self.tableView endUpdates];

UITableView deleteRowsAtIndexPaths not working

I'm not quite sure what's going on here but I'm running into a contact form that I'm working with. In my form I've added the ability to add an email address to a contact. As pictured below, once the user clicks on "add email", a row is added to the "Emails" section.
However after I click to delete the email, an extra cell appears underneath the add email button (pictured below).
There's a little red box from what appears to be the prior delete cell as though the table isn't reloaded. Here's my delete code:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if( editingStyle == UITableViewCellEditingStyleDelete )
{
// Update the data source
NSMutableArray *fields = (NSMutableArray *)self.fields[#(indexPath.section)];
[fields removeObjectAtIndex:indexPath.row];
NSMutableArray *values = (NSMutableArray *)self.values[#([self fieldTypeAtIndexPath:indexPath])];
[values removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationMiddle];
}
}
So why is that cell remaining afterwards? I can call [tableView reloadData] within the method above and it removes the excess cell but then it messes up the animation. Can you shed some clarity on what I'm doing wrong here?
This looks like a bug.
I just noticed that even Apple has this same bug in their Reminders app. It seems to be related to deleting rows from a UITableView with variable height items.
In Apple's Reminders app, when you delete something from a long list with variable height items, you will see the same exact visual artifact for a split second. Then the table jumps and the list looks correct. I am assuming Apple just reloads the entire table view a second after the item is removed in order to fix the visual glitch.
My recommendation is to report this as a bug to Apple. For now you can reload the entire table view like Apple presumably does.
Option 1: Before you call deleteRowsAtIndexPaths, you must make sure that numberOfRowsInSection will return the correct value (e.g. if you originally had 2 rows in that section, it should now return 1 row).
Option 2: If that isn't the problem, I would try a different animation type (e.g. UITableViewRowAnimationAutomatic), just to see if that has any effect.
Option 3: Ensure that cellForRowAtIndexPath is returning a valid cell with its contents being reset. Otherwise it may be reusing an invalid cell or displaying something that was there before.
Option 4: Since the heights are different, ensure that heightForRowAtIndexPath is returning the correct value. You probably need to call reloadRowsAtIndexPaths in order for the table view to know about the height difference.
I had the same problem and I guess it might be a bug in iOS7 where it doesn't repaint the cells correctly, I fixed it but not in an efficient way, just in the "cellForRowAtIndexPath" , always create a new cell, don't dequeue it.

Hide Delete button from UITableViewCell

When my table view is in edit mode, the red (-) buttons appear.
When the user taps one of them the [Delete] button appears.
When the user taps on [Delete] I first check a few things (partly online). This delete may not be allowed.
When deleting that cell is not allowed, how do I hide the [Delete] button and let the red (|) button become a (-) again in an animated way? So, I don't want my whole table to leave editing state.
To get the actual animation (Instead of the UITableViewRowAnimationRight/UITableViewRowAnimationAutomatic) animations, just do
[self.tableView beginUpdates];
[self.tableView setEditing:NO animated:NO];
[self.tableView setEditing:YES animated:NO];
[self.tableView endUpdates];
beginUpdates and endUpdates provide the animation, and the tableView is just switched from not editing to editing instantly, which closes the delete button.
Hope this helps!
I've run into this issue myself where I may bring up an alert view to prompt the user further and wish to reset the delete button if they choose not to proceed. This seems like the easiest approach, assuming deleteIndexPath is the index path of the row selected for deletion:
[self.tableView reloadRowsAtIndexPaths:#[deleteIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
I now see that you want to disable delete for only certain cells. You can do this in a couple of ways:
tableView:canEditRowAtIndexPath method: Return NO where you want DELETES to be DISABLED.
tableView:canMoveRowAtIndexPath: Return YES where you want to allow reordering.
You may want to think about sub-classing UITableViewCell to give it some ability to maintain its own state (so the cell knows if delete is allowed or not. Then you can interrogate the actual cell instance and determine if you should enable delete even after the list may be re-ordered.
To hide any icon in whole table view, then in your controller just ,
override EditingStyleForRow and return UITableViewCellEditingStyle.None
None: will hide any icon of left of items of table view,
delete: will show remove icon
Insert: will show add icon

How to know that no row is selected in my UITableView?

I use a UITableView to display a list of items, and when a row is selected I show that item in a detail view next to it (using a split view controller).
As the selection in the table view changes I want my detail view to change as well, which is of course standard behavior and it works flawlessly... except when no row is selected anymore in the table view.
Users can for example delete a row from the table view, and during and also after that deletion there will be no selected row in the table view. Of course after a row is deleted I let my detail view controller know, but during the editing process in the table view, when no row is selected, my detail view controller does not know this.
I tried to use the UITableViewSelectionDidChangeNotification but that only gets sent when the user selects a different row, not when a deselection occurs.
How can I be notified of the fact that the table view switches from having a row selected to having no selection at all?
EDIT:
As a temporary solution, I tried renaming the Edit-button to "Reorder" and only allowing moving rows from A to B but without allowing the deletion controls, but this can not be done, there is no move control without enabling editing on a row. The thing is, I do get a pointer to a row that is up for moving, so I can keep that selected. I do not get this pointer for a row up for deletion, so no go for me. I always want to know what row a user works on, and keep that row selected at all times.
I may have to resort to ditching the standard editing behavior and adding my own buttons and methods for it. Or see what gestures can do for me to capture touches on any row...
There is a property indexPathForSelectedRow. I'm not sure what it would return when there is no selected row, but it may return nil or something like that, which you could use as a trigger to know if there are any rows selected. Something like
if (myTable.indexPathForSelectedRow == nil)
{
//do something here to account for no rows being selected
}
else
{
//do stuff here to set up your detail view
}
Let me know if this works for you.
How are you implementing the deletion of rows? Are you implementing the following data source method?
tableView:commitEditingStyle:forRowAtIndexPath:
You can have a property like
NSIndexPath *selectedIndexPath
and set it to nil when a row is being deleted.
Example:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
//select another row in your table
[tableView selectRowAtIndexPath:*indexPathOfTheRowToBeSelected* animated:YES scrollPosition:UITableViewScrollPositionNone];
//then delete row from data source
}
The method above will be called when the user touches the delete button on the table he/she has selected to delete.
Okay I misread what you were asking at first, I'm pretty sure what you want is either – tableView:willDeselectRowAtIndexPath: or – tableView:didDeselectRowAtIndexPath:. These methods will be triggered automatically when the user deselects a row (either right before the row is deselected or right after, respectively). Implement one of these in your table view delegates code, and you'll know whenever a row gets deselected, and you can put your code to select the next row or whatever you want in one of these methods.
I struggled with this as well. Turns out that when the "Edit" button is hit, all rows are deselected at that point. You can override setEditing:animated: to detect when it is hit, but you must call [super setEditing:editing animated:animated] before you return.
See this link for where I found this:
How can i identify self.editButtonItem button's clicked event?

Grouped TableView selection problem

Ok, I have a grouped TableView that has the following overridden method:
-(NSIndexPath*)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath{
return nil;
}
... Obvious enough, to disable selection.
BUT!
If the user presses and holds on a cell, it gets highlighted (selected)!! I need to disable this, too.
On a side note, I am using the tableView to display static Data, almost like the About tableView in Settings > General. It just loads the info from an array of strings that I created manually.
If there is a better way to represent the data, please do tell!
Thanks!
Set the selectionStyle property of the cell to UITableViewCellSelectionStyleNone.
See the documentation for tableView:willSelectRowAtIndexPath: to see why this is needed even though you're indicating that you don't want the cell selected.
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
...did the trick.

Resources