I have a custom UITableViewCell called CustomCell which has a UILabel in it which it is supposed to show the current index number + 1 (It is a queue of things to do).
I am using the setEditing method to allow the users to move cells around however I just cannot get the cells to be numbered correctly (in order) with the following code. Basically I am just trying to access the cells in the region the method parameters are passed but the numbers are simply returning out of order. What am I doing wrong here?
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
[queuedToDoArray moveObjectAtIndex:fromIndexPath.row toIndex:toIndexPath.row];
NSIndexPath *lowerIndexPath = (fromIndexPath.row < toIndexPath.row ? fromIndexPath : toIndexPath);
NSIndexPath *higherIndexPath = (fromIndexPath.row > toIndexPath.row ? fromIndexPath : toIndexPath);
//Update all the queue numbers in between moved indexes
for (int i = lowerIndexPath.row; i <= higherIndexPath.row; i++) {
NSIndexPath *currentIndexPath = [NSIndexPath indexPathForRow:i inSection:0];
CustomCell *currentCell = [todoTable cellForRowAtIndexPath:currentIndexPath];
[currentCell.queueNumber setText:[NSString stringWithFormat:#"%i", currentIndexPath.row + 1]];
}
}
You should not configure your tableview cell a.k.a customCell in moveRowAtIndexPath method, instead, just updating the data-model array for the relocated row.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {
NSString *stringToMove = [self.queuedToDoArray objectAtIndex:sourceIndexPath.row];
[self.queuedToDoArray removeObjectAtIndex:sourceIndexPath.row];
[self.queuedToDoArray insertObject:stringToMove atIndex:destinationIndexPath.row];
}
After that, just call [self.tableView reloadData] and it will automatically do that for you.
Please check out the Apple Developer Document for more details.
Edit:
A better solution is just reloading the relative sections or rows as #Paulw11 commented.
Related
A UITableView which have UITableViewCell of 20 rows, each row do have one button on it, click button I want to drop the UITableViewCell to bottom to UITableView.
Is there any delegate method which do for it.
Your feedback will be appreciated.
Yes, there is a method on tableview
- (void)moveRowAtIndexPath:(NSIndexPath*)indexPath
toIndexPath:(NSIndexPath*)newIndexPath
You can read more https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableView_Class/#//apple_ref/occ/instm/UITableView/moveRowAtIndexPath:toIndexPath:
Yes, there is one!
Use below delegate methods for that:
have to return YES to allow moving of tableView row in canMoveRowAtIndexPath delegate method as per your requirement,
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0) // Don't move the first row
return NO;
return YES;
}
Then, use moveRowAtIndexPath delegate method to Updating the data-model array for the relocated row accordingly,
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath
toIndexPath:(NSIndexPath *)toIndexPath
{
//Updating the data-model array
}
Like moveRowAtIndexPath in button click,
- (void)btnClick:(UIButton*)sender
{
UITableViewCell *cell = (UITableViewCell *)sender.superview;
NSIndexPath *indexpath = [tableView indexPathForCell:cell];
//Change accordindly as per requirement
[tableView moveRowAtIndexPath:[NSIndexPath indexPathForItem:indexpath.row inSection:indexpath.section] toIndexPath:[NSIndexPath indexPathForItem:0 inSection:indexpath.section]];
}
Also, read Apple documentation for same:
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TableView_iPhone/ManageReorderRow/ManageReorderRow.html
I have a bunch of cells, all of which have a label that displays its row. When I move cells in the table, I would like the cells to renumber according to their new rows. After trying the code below, the numbers are all off. How would I fix this?
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{
for (int section = 0; section < [tableView numberOfSections]; section++) {
for (int row = 0; row < [tableView numberOfRowsInSection:section]; row++) {
NSIndexPath* cellPath = [NSIndexPath indexPathForRow:row inSection:section];
CustomCell* cell = (CustomCell *)[tableView cellForRowAtIndexPath:cellPath];
NSString *rowString1 = [NSString stringWithFormat:#"%d.", row + 1];
cell.periodLabel.text = rowString1;
}
}
}
Let Model-View-Controller be your friend.
Instead of thinking "renumber the cells", think "renumber the objects". Use a Model object (say MyNumberedRow) to represent the data in the cell. When the cell moves, retrieve that cell's MyNumberedRow instance, update that.
Even if you have hundreds of items in your logical table, you'll only see a few of those realized as CustomCell instances. If it's not on screen, the cell won't exist.
Side note: use NSInteger, not int. It avoids type problems in 32/64 bit conversions. It's also the return type of -numberOfSections.
I implemented the body of the method moveRowAtIndexPath:toIndexPath: as follows:
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
XYZToDoItem *itemToMove = [self.toDoItems objectAtIndex:fromIndexPath.row];
NSLog(#"Moving");
NSLog( itemToMove.itemName);
[self.toDoItems removeObjectAtIndex:fromIndexPath.row];
[self.toDoItems insertObject:itemToMove atIndex:toIndexPath.row];
}
I'd like to call this method from TableViewController's didSelectRowAtIndexPath method.
When I do the rows of the table do move, but the above method doesn't seem to execute. Nothing logs to the console and the items in the array toDoItems DO NOT swap.
Here's the body of that method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSIndexPath *indexPathOfLastItem =
[NSIndexPath indexPathForRow:([self.toDoItems count] - 1) inSection:0];
[tableView moveRowAtIndexPath:indexPath toIndexPath:indexPathOfLastItem];
}
How do I get the table view to move rows properly from within the delegate (the TableViewController)?
Moving (or adding, removing) table view rows by code (and not by user interaction) does not cause the
data source methods to be called.
If you need the data source method to be executed, you need to call it explicitly:
// Move table view row:
[tableView moveRowAtIndexPath:indexPath toIndexPath:indexPathOfLastItem];
// Call data source method:
[self tableView:tableView moveRowAtIndexPath:indexPath toIndexPath:indexPathOfLastItem];
Swift 3:
// Move table view row:
tableView.moveRow(at: indexPath, to: indexPathOfLastItem)
// Call data source method:
self.tableView.moveRow(at: indexPath, to: indexPathOfLastItem)
I don't think you're calling the method correctly, since it's not a real delegate method you have to call it on self.
Try:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSIndexPath *indexPathOfLastItem =
[NSIndexPath indexPathForRow:([self.toDoItems count] - 1) inSection:0];
[self tableView:tableView moveRowAtIndexPath:indexPath toIndexPath:indexPathOfLastItem];
}
I have a "UITableView", I am trying to handle selected row and use its data accordingly,
I have written necessary code to take the selected row, unfortunately it seems it does not work
If i select nothing,
NSIndexPath *path = [tableViewDoctorName indexPathForSelectedRow];
int rowSelected = path.row;
rowSelected's value is 0;
But, when i select the row it is again 0.
I have only one row in a table, i am not sure does it matter?
How can i accurately determine the selected row in a "UITableView"?
Set the UITableView delegate and implement this method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
int rowSelected = indexPath.row;
}
indexPath.row start with 0 for first row, And you have only one row then it return always 0;
But if you want to get data of selected Row then you delegate method of UITableView.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// here you can get directly indexPath.row so you can get required data;
}
Of course how many rows you have in your tableView matters : if you only have 1, then its indexpath is (0 ,0) and this is the only one that can be (selected) in this case.
The selected row generally is highlighted (in blue) so you might want to store it in another property of your tableView delegate, if you don't want this blue selection to stay on-screen.
Typically, in your UITableViewDelegate :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// deselect the row, to avoid the 'blue' selection to stay on-screen
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// save your own copy of 'last' selected indexPath
self.mySavedIndexPath = indexPath;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
_selectedIndexPath = indexPath;
}
In outside the function,
use this to get selected row,
NSIndexPath *indexPath = [NSIndexPath indexPathForRow: _selectedIndexPath.row inSection:0];
int rowSelected = indexPath.row;
I have a tableview that won't reorder. It looks like moveRowAtIndexPath is never called with a sourceIndexPath that is different from the destinationIndexPath. When I pull a row, it bounces back to its starting location as if the row didn't support movement.
I tried implementing all the "canMove/canEdit/propose" methods to return YES, but I observe the same behavior. What's going on?
- (void) tableView:(UITableView *)tableView
moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath
toIndexPath:(NSIndexPath *)destinationIndexPath {
NSLog(#"%d -> %d", [sourceIndexPath row], [destinationIndexPath row]);
if ([sourceIndexPath row] == [destinationIndexPath row]) {
return;
}
MyDomain *domain = [self getObject];
[domain.stuff exchangeObjectAtIndex:(NSUInteger) [sourceIndexPath row] withObjectAtIndex:(NSUInteger) [destinationIndexPath row]];
}
I'm using IIViewDeckController, which cancels panning in views.
When setting up the ViewDeckController, do this:
self.panningCancelsTouchesInView = NO;