I have a UItableview with reordable rows and the data is in an NSarray. So how do I move an object in the NSMutablearray when the appropriate tableview delegate is called?
You can't. NSArray
is immutable. You can copy that array into an NSMutableArray (or use that in the first place). The mutable version has methods to move and exchange its items.
id object = [[[self.array objectAtIndex:index] retain] autorelease];
[self.array removeObjectAtIndex:index];
[self.array insertObject:object atIndex:newIndex];
That's all. Taking care of the retain count is important, since the array might be the only one referencing the object.
I guess if I understand correctly, you can do:
- (void) tableView: (UITableView*) tableView moveRowAtIndexPath: (NSIndexPath*)fromIndexPath toIndexPath: (NSIndexPath*) toIndexPath
{
[self.yourMutableArray moveRowAtIndex: fromIndexPath.row toIndex: toIndexPath.row];
//category method on NSMutableArray to handle the move
}
Then what you can do is to add a category method to NSMutableArray using – insertObject:atIndex: method to handle the move.
Similar to Tomasz but with out of range error handling
enum ArrayError: ErrorType {
case OutOfRange
}
extension Array {
mutating func move(fromIndex fromIndex: Int, toIndex: Int) throws {
if toIndex >= count || toIndex < 0 {
throw ArrayError.OutOfRange
}
insert(removeAtIndex(fromIndex), atIndex: toIndex)
}
}
If you have an NSArray
, you can't move or reorder anything as it is immutable.
You need an NSMutableArray
. With that, you can add and replace objects which, of course, also means you can reorder the array.
ARC compliant category:
NSMutableArray+Convenience.h
@interface NSMutableArray (Convenience)
- (void)moveObjectAtIndex:(NSUInteger)fromIndex toIndex:(NSUInteger)toIndex;
@end
NSMutableArray+Convenience.m
@implementation NSMutableArray (Convenience)
- (void)moveObjectAtIndex:(NSUInteger)fromIndex toIndex:(NSUInteger)toIndex
{
// Optional toIndex adjustment if you think toIndex refers to the position in the array before the move (as per Richard's comment)
if (fromIndex < toIndex) {
toIndex--; // Optional
}
id object = [self objectAtIndex:fromIndex];
[self removeObjectAtIndex:fromIndex];
[self insertObject:object atIndex:toIndex];
}
@end
Usage:
[mutableArray moveObjectAtIndex:2 toIndex:5];