Reorder NSArray based on UITableView Edit - ios

I have an app filled with over 500 songs for churches. I am adding a new feature, which will allow them to create a "slide show" of manually chosen songs. The way the layout is now is that they have a UITableView of all the songs, and tapping a song adds that PPT's file location to an NSArray, and adds a checkmark to the row. Following this, they can click the Preview button, which will give them a tableview of just the songs they have chosen, in the order they chose it.
I would like to allow editing mode to delete songs, or reorder them, but am not sure how to have that also reorder the NSArray, so that item 0 will be the first song they have on the tableview, not just the first one they tapped.

I assume you have an array of songs, called songsArray which is used to populate table view. Then when reordering happens, add this method.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {
NSObject *songToMove = [self.songsArray objectAtIndex:sourceIndexPath.row];
[self.songsArray removeObjectAtIndex:sourceIndexPath.row];
[self.songsArray insertObject:stringToMove atIndex:destinationIndexPath.row];
}
Dont forget to implement canMoveForRowAtIndexPath
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
This lets user to reorder all rows in your table view, if you don't want to let user to reorder specific rows, add check for indexPath.row and return NO for that row.

Related

How to Save UITableViewController cells after rearrange to NSUserDefaults

I've an iOS application developed using Objective-C & Xcode 6.4
Right know I'm working on manually rearranging the UITableViewController cells, everything working great. But after I press the bar button EDIT and the "3 underlines" appear to drag the cell anywhere I want in the UITableViewController, (( I can't save what I did )). So how could I do a Persistent save the changes done to the table cells location ?? I mean, How to save The new rearranged NSMutableArray to a Property list -NSUserDefaults-.
I'm using a Mutable Array to display the table's cells and these methods below:
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleNone;
}
-(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
FileWML *fileWML = [self.filesWML objectAtIndex:sourceIndexPath.row];
[self.filesWML removeObjectAtIndex:sourceIndexPath.row];
[self.filesWML insertObject:fileWML atIndex:destinationIndexPath.row];
}
PLUS would someone tell me how I can make the edit button display the word Done, while editing ?
(( I can't save what I did )) means: after I do the rearranging order I want, and then I go to the home view then I get back to the table view I edit and rearrange, the rearranging order I did get back to the default order. So, all the rearranging I did is gone.
Thanks and every help is appreciated.
You have to load your datas from your file in an array. This array will be your tableView dataSource.
When a row is moved, in the delegate method you have to change the object's place in the array. Your array should always be the same as your tableview !
Once the editing of the tableview is done you save the array in the file. The previous content in file should be erased. Then you reload your datas ([tableView reloadData].

Adding new cells in a particular position in UITableView

I just started learning iOS programming and have a requirement where the user is able to edit their profile (adding emails, numbers , etc). I wanted to do it like how the native Contacts app of iOS7+ does for adding new contacts. You see a cell saying "add phone" and when you tap it you get a new cell just above it. as you tap the "add phone" cell you get new cells piling up above. Can anyone point me in the right direction to achieve similar results. Thanks for any help in advance.
There's a few different ways to insert a cell into a table view. You can add cells in an animated fashion using the table's insertion style in the table view's editing modes.
It may be easier to just add an entry to your data source array at the desired index and call [tableView reloadData]
For example if the add phone button was the last cell in the table:
in didSelectRowAtIndexPath:
if (indexPath.row == mutableArray.count - 1) {
// Clicked add phone button
[mutableArray addObject:/*phone cell placeholder*/ atIndex:mutableArray.count - 1];
tableView reloadData];
}
After your table view reloads, there will be a new cell above the last cell where you can add a text field to enter a phone number.
You need to add that cell's data in your data source and call reload ...a simple one.
for showing delete or insert button you need to use
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (<condition>) {
return UITableViewCellEditingStyleInsert;
}
else {
return UITableViewCellEditingStyleDelete;
}
return UITableViewCellEditingStyleNone;
}
for action specific to rows you can use following methods
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation NS_AVAILABLE_IOS(3_0);
- (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath NS_AVAILABLE_IOS(5_0);

How to disable all unselected cells in a UITableView

Is there a way to disable all of the cells within a UITableView that aren't being used? Within my application a user chooses a max of two cells and after two cells are selected I want all other cells to be disabled but I can't figure it out. Any help would be greatly appreciated, thanks!
You don't want to disable the rows, you want to prevent the user from selecting additional rows, right?
Implement the tableView:willSelectRowAtIndexPath: delegate method. If there are already two rows selected you should return nil, otherwise return the index path.
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (/* check if there are already two selected rows */) {
return nil;
} else {
return indexPath;
}
}

Core Data - Reordering TableView won't save

.
Hello,
I have the following code to set the re-ordering of the tableView.
#pragma mark Row reordering
// Determine whether a given row is eligible for reordering or not.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
// Process the row move. This means updating the data model to <span id="IL_AD6" class="IL_AD">correct</span> the item indices.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath
toIndexPath:(NSIndexPath *)toIndexPath {
NSString *item = [arr objectAtIndex:fromIndexPath.row];
[arr removeObject:item];
[arr insertObject:item atIndex:toIndexPath.row];
}
But when I reload the TableView (note not a TableViewController) The order is set back to what it was before I changed anything.
Now when I setup the editing for this view (the delete buttons) I had to add this line:
[self.mainTableView setEditing:YES animated:YES];
before it appeared in my view.
Is there a similar thing I need to set with the re-ordering of the table view for it to save?
The data is fetched from a Core Data database.
In order to persist the order of the objects I'm afraid you will need to add an attribute for that to your data model. Just use an int / [NSNumber] and recompute them in a loop when a table view row is moved.
When you reload the data, are you re-populating that array with the result of a fetch from your Core Data entity? If so, the changes you made to the array (which I assume is the data source for the TV) will be blown away. If you want those changes to stick, you would need to update the model somehow to make sure the re-population of the array results in the array being indexed the way you need.

UITableViewCell: Allowing Selective Deletion

I have a table view and want to allow reordering of all cells, however there are certain cells that I do not want to be allowed to be deleted. when the UiTableView is put into deletion mode I do not want the red '-' button to appear on the left hand side, and do not want the swipe gesture to bring up the Delete button of these cells but want it to happen for the others. Any ideas?
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
//if we cant delete the object represented at the index path
if ([[tableViewObjectsArray objectAtIndex:indexPath.row] canBeDeleted] == NO){
return UITableViewCellEditingStyleNone;
}
//otherwise allow the deletion
else{
return UITableViewCellEditingStyleDelete;
}
}
Of course this leaves an empty space where the '-' button should be, but it does not allow deletion. And also does not allow the swipe deletion either.
implement:
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}

Resources