Cannot make table re-order to work - objective-c

From the UITableViewCell showsReorderControl docs:
For the reordering control to appear, you must not only set this property but implement the UITableViewDataSource method tableView:moveRowAtIndexPath:toIndexPath:. In addition, if the data source implements tableView:canMoveRowAtIndexPath: to return NO, the reordering control does not appear in that designated row.
I've got the both in my tableviewController :
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
NSLog(#"move from:%d to:%d", fromIndexPath.row, toIndexPath.row);
//just for test
}
My cell properties including re-order controls :
And yet I can't see the re-order control, what am I missing?

Have you put your UITableView into editing mode via
[tableView setEditing:YES animated:YES];
?
The first method you posted is needless, by the way, as that is the default behavior.

I think you need to actually get into edit mode for the table. Either try it in code when your view appears or create a button that will do it.
[tableView setEditing:YES animated:YES];

Related

Make 'edit' button trigger edit-mode on UITableView

This might be a very stupid question, but I have very little knowledge about Xcode, Objective-C and iOS development in general.
What I have is a UITableViewController, with a number of cells. I've gotten the 'add' and delete (swipe to delete) functions to work, but I cannot figure out how to connect the 'edit' button to a function that will trigger the editing mode of that TableView, so I can rearrange the order of the elements.
I have un-commented these functions:
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
XYZToDoItem *itemToMove = [self.toDoItems objectAtIndex:fromIndexPath.row];
[self.toDoItems removeObjectAtIndex:fromIndexPath.row];
[self.toDoItems insertObject:itemToMove atIndex:toIndexPath.row];
[self.tableView reloadData];
}
As you can see I have also made a few additions to the moveRowAtIndexPath method following the documentation.
In addition there are these functions;
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[self.toDoItems removeObjectAtIndex:indexPath.row];
[self.tableView reloadData];
}
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
As previously stated the "swipe to delete" function works, I don't know how, but I simply just uncommented these last two methods and edited one a bit to fit my code.
To be more specific, what I'm asking is how can I link the 'edit' button I have in my Navigation Controller to trigger the edit mode for the TableView, thereby showing the three lines (?) known from the TableViews editing mode (and letting me drag the elements to an order I want).
Thanks in advance for all your help! :)
If this is a UITableViewController you have two options. Either use the built-in edit button, which will give you the automatic Edit/Done button change. Use self.editButtonItem in your navigation bar:
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
Or you could use setEditing:animated to change editing state of the tableViewController:
// self is a UITableViewController
[self setEditing:YES animated:YES];
If your viewController is not a subclass of UITableViewController you can set the editing mode of the tableView:
[self.tableView setEditing:YES animated:YES];
If you have a UITableViewController you should use the first way because it is most convenient.

How reorder row in customize UITableViewCell

So far I have customized my UITableViewCell with the icon reorder row.
I want my cell can be reordered when long press on the reorder icon and then move it.
The image below is what I have expected.
I have read many document they provided only long press on cell and move it but I don't want it because long press on cell I have my another gesture is renaming it; and also I don't want to use the edit/done of UITableView default from OS; so I decided to put reorder icon but I can not do, because I'm new in objective c.
Can anyone help by providing sample code here?
Thank for reading.
Override two methods of UITableViewDataSource
For reordering to work you will first need to bring the Table in editing mode. Which you can either do it from viewDidLoad or from a IBAction method.
-(void) viewDidLoad{
[super viewDidLoad];
self.myTableView.editing = YES;
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath{
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath{
//Manipulate your data array.
}
By Default editing style is UITableViewCellEditingStyleDelete. So if you don't override the below method it will show both rearrange as well delete icon.
-(UITableViewCellEditingStyle) tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewCellEditingStyleNone;
}
Since, you have long gesture of your cell causes issue with the long gesture of the re-ordering of cell. You can add a UIView to the cell. Add all your elements in this UIView. Now, attach a UILongPress Gesture to this UIView (not to the cell.).

cellForRowAtIndexPath is called when there is no row

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
if ([BGSearchParameter defaultSearchParameters].fetchedResults.count==0)
{
PO(#([self.tableView numberOfRowsInSection:0]));
PO(#([self tableView:nil numberOfRowsInSection:0]));
PO(#(indexPath.row));
while (false);
}
This is the result
self.tableView numberOfRowsInSection:0]): 20
#([self tableView:nil numberOfRowsInSection:0]): 0
Now, I do not know who call that cellForRowAtIndexPath.
Here is the screenshot
The debuggin windows shows that the main thread somehow call cellForRowAtIndexPath.
I usually fix this issue by returning some random UITableViewCell that's never displayed. Howerver, I think it's a bug.
What functions can call cellForRowAtIndexPath anyway besides tableReload and why it doesn't call
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
first?
It seems that my tableView still think there are 20 rows even though there are only 0 rows.
The issue seems to be your tableview is not refreshing. Please include this line in your code so that it will refersh each time:-
[yourTableView reloadData];
You can use the parameter "tableView" of this method to check whether the right instance of "UITableView" is called. For example, in the delegate method" - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section" add these code:
if(tableView== youwanttocheckTableView) {
//do what you want to do
}
You can also check which TableView instance have set its delegate equals "self" in this class.

How to show deleteConfirmationButton on a clicked UITableViewCell

I'm trying to make an UITableViewCell that shows the deleteConfirmationButton (while in edit mode) just like happens when I click at the editing controls but in my case I want it when the user clicks over the UITableCell.
I've already set the property AllowsSelectionDuringEditing to YES and I can delete the rows, I just want the deleteConfirmationButton to avoid any accident.
Any tips on how to do it?
Thanks!!
To do this you would probably use the commitEditingStyleForRowAtIndexPath function, which is called when an object is selected or deleted during editing.
- (BOOL)tableView:(UITableView *)tableView
canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
And then for the confirmation do something like this:
- (void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
{
//make a UIAlert and display confirmation, if yes then run the following code, if no then break
// remove the object
[myItems removeObjectAtIndex:indexPath.row];
// refresh the table view to display your new data
[tableView reloadData];
}

How to unselect a UITableViewCell after you have done some action using didSelectRowAtIndexPath?

Currently I do some work inside the didSelectRowAtIndexPath delegate and noticed that my row is still "selected" after I come back to the view controller later.
How can I unselect this row inside the delegate itself?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//do logic and ... it remains selected in the view?
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
Typically, you want to deselect the row when the view controller appears again:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
}
That's what UITableViewController does implicitly, and animating the deselection process after the view controller appears again is a helpful hint to the user as to which cell they selected previously.