【问题】
在折腾:
给Your Second iOS App的BirdWatching添加让列表可修改,可排序
过程中,遇到需要重排表格中的cell,即允许手动拖动,改变cell的顺序。
【解决过程】
1.已经参考官网资料:
Managing the Reordering of Rows
了,其也给出了参考代码:
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.row == 0) // Don't move the first row return NO; return YES; }
和
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath { NSString *stringToMove = [[self.reorderingRows objectAtIndex:sourceIndexPath.row] retain]; [self.reorderingRows removeObjectAtIndex:sourceIndexPath.row]; [self.reorderingRows insertObject:stringToMove atIndex:destinationIndexPath.row]; [stringToMove release]; }
但是说实话,canMoveRowAtIndexPath的使用是很简单,但是对于moveRowAtIndexPath的实现,就看不太懂了。
因为其中的reorderingRows是从哪里来的,还是没搞懂。
2.网上搜资料,也找到了些moveRowAtIndexPath相关的代码:
UITableView的moveRowAtIndexPath的代码
但是都还是看不太懂。
3.不过,对于上述moveRowAtIndexPath中的实现逻辑,倒是很容易明白:
就是得到from的对象且同时retain,然后删除from,插入retain的from对象到to的位置,即可。
感觉很是繁琐。
4.后来通过:
What methods do I have to implement in order to re-arrange the UITableView rows?
知道了有个函数
exchangeObjectAtIndex:withObjectAtIndex:
看着名字,就感觉很像是能够实现两者object交换的功能。
如果能够使用,至少比上述moveRowAtIndexPath中的实现逻辑要简洁明了。
5.不过,后来找到了官网的解释:
exchangeObjectAtIndex:withObjectAtIndex:
关于其是否能在我当前的iOS中使用,还担心了一把,因为其原始定义为:
exchangeObjectAtIndex:withObjectAtIndex:
Exchanges the objects in the array at given indices.
– (void)exchangeObjectAtIndex:(NSUInteger)idx1 withObjectAtIndex:(NSUInteger)idx2
Parameters
- idx1
The index of the object with which to replace the object at index idx2.
- idx2
The index of the object with which to replace the object at index idx1.
Availability
- Available in OS X v10.2 and later.
Declared In
NSArray.h
很明显,其说的是OS X中 v10.2之后可以使用,但是没有提到iOS中是否可用。
6.关于上述moveRowAtIndexPath中,如何获得对象数组,经过一番找寻,最后终于找到,我此处,应该如何实现了。
详情放在最后的总结部分。
7.另外,关于exchangeObjectAtIndex在iOS是否可用:
经过实际测试,确定iOS中也是可以使用exchangeObjectAtIndex的:
8.最终就可以去实现对应的代码,实现table中的cell的拖动,调整顺序了。
下面对相关内容进行总结:
【关于UITableView中如何拖动UITableViewCell】
由于之前没有Mac的程序的使用经验,导致对于UITableViewCell,无论如何点击,对无法实现拖动。
后来经过摸索,才知道,是这样的:
即,点击那个reordering control,即灰色的,三行的,那个小图标,说明当前行是可以被拖动然后调整顺序的。
点击reordering control超过一段时间(估计多少微秒)即可出现灰色边框,然后就可以随心所欲的拖动到别的地方了。
【moveRowAtIndexPath函数中实现交换两个cell的逻辑】
对于canMoveRowAtIndexPath中,就不啰嗦了,直接renturn YES,即可:
// Override to support conditional rearranging of the table view. - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { // Return NO if you do not want the item to be re-orderable. return YES; }
下面详细解释,如何实现moveRowAtIndexPath中cell交换的逻辑:
1.首先一定要找到你当前UITableView所对应的,用于存储数据的那个数组
很多时候,该数组都是NSMutableArray类型的。
比如我这里的,当前是要在文件BirdsMasterViewController.m中去实现moveRowAtIndexPath函数。
但是,其所对应的UITableView的数据来源则是在另外别的文件BirdSightingDataController.h中masterBirdSightingList,相关代码为:
@property (nonatomic, copy)NSMutableArray *masterBirdSightingList;
此masterBirdSightingList是个数组变量,保存相关的每个UITableViewCell的数据。
即,搞懂UITableView中保存数据的是哪个数组。
得到了保存数据的数组,才能接着获得对应的每个cell对象,然后继续后续操作。
2.然后使用函数exchangeObjectAtIndex实现两个cell对调:
(此处不使用前面所提到的官网中的逻辑:先retian,再remove,再insert)
相关代码为:
// Override to support rearranging the table view. - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { [self.dataController.masterBirdSightingList exchangeObjectAtIndex:fromIndexPath.row withObjectAtIndex:toIndexPath.row]; }
如此,即可实现将from和to两个cell进行对调了。
最终实现了对应的效果:
【总结】
其实,此处本质上只是一个数组Array内的两个object对换位置。
而实际上你所看到的界面中的显示出来的效果,其实就是UITableView,从此处的 保存数据的数组masterBirdSightingList,获得对应的每个cell的数据,然后上层再负责显示。
即你只操作了TableView的DataSource,就相应的实现了UITableView显示出来的,对应cell调换的效果了。
转载请注明:在路上 » 【已解决】如何实现iOS中的UITableViewCell的重排,即如何实现moveRowAtIndexPath函数