Problem
在表视图里面通过流畅而直观的动画来移动改变cell 和section 的位置
Solution
使用 moveSection: toSection 表视图方法,将部分移动到一个新的位置。您还可以使用moveRowAtIndexPath: toIndexPath: 方法移动表视图单元格从当前位置到另一个新的地方
Discussion
移动表视图细胞和部分不同于交换他们。让我们来看一个例子,这将使这个更容易理解。比方说,你有三个部分中的表视图:第A, B和C。如果您移动部分A到C组,表视图会注意到这一举动,然后将B部分转移到A段之前的位置,并将移动C节第B的前面的位置但是,如果B段被移动到C组,表视图不会有移动A节可言,因为它是坐在上面,并不会与重新定位干扰B段和C在这种情况下, B段将被移动到C段和C段第B移动单元格时,同样的逻辑也将使用表格视图。
为了证明这一点,让我么创建一个表视图,并拥有三个section,每个section包含三个预先加载的三个cell。让我们开始我们的视图控制器的实现文件:
#import “ViewController.h”
static NSString *CellIdentifier = @“CellIdentifier”;
@interface ViewController () <UITableViewDelegate,UITableViewDataSource>
@property (nonatomic,strong) UITableView *myTableView;
@property (nonatomic,strong) NSMutableArray *arrayOfSections;
@end
我们的视图控制器将成为本表视图的数据源。该表视图有部分,每个部分都有行。我们将继续数组的数组,数组的第一个是我们的阵列部分,这将本身包含包含我们的cell其他数组。在我们的视图控制器的实现文件的顶部定义的arrayOfSections将承担这一责任。让我们继续前进,填充这个数组:
- (NSMutableArray *) newSectionWithIndex:(NSUInteger)paramIndex cellCount:(NSUInteger)paramCellCount{
NSMutableArray *result = [[NSMutableArray alloc] init];
NSUInteger counter = 0;
for(counter = 0; counter < paramCellCount; counter++){
[result addObject:[[NSString alloc] initWithFormat:@“Section %lu Cell %lu”,(unsigned long)paramIndex,(unsigned long)counter+1]];
}
return result;
}
- (NSMutableArray *) arrayOfSections{
if (_arrayOfSections == nil){
NSMutableArray *section1 = [self newSectionWithIndex:1 cellCount:3];
NSMutableArray *section2 = [self newSectionWithIndex:2 cellCount:3];
NSMutableArray *section3 = [self newSectionWithIndex:3 cellCount:3];
_arrayOfSections = [[NSMutableArray alloc] initWithArray:0[section1,section2,section3]];
}
return _arrayOfSections;
}
然后我们将实例化表格视图和实现UITableViewDataSource协议必要的方法来填充我们的数据表视图:
- (NSInteger) numberOfSectionInTableView: (UITableView *)tableView{
return self.arrayOfSections.count;
}
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
NSMutableArray *sectionArray = self.arrayOfSections[section];
return sectionArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSMutableArray *sectionArray = self.arrayOfSections[indexPath.section];
cell.textLabel.text = sectionArray[indexPath.row];
return cell;
}
- (void)viewDidLoad{
[super viewDidLoad];
self.myTableView = [[UITableView alloc] initWithFrame:self.bounds style:UITableViewStyleGrouped];
[self.myTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:CellIdentifier];
self.myTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.myTableView.delegate = self;
self.myTableView.dataSource = self;
[self.view addSubView:self.myTableView];
}
展示时间!!!咱们先来看看部分如何被移动到新的位置?让我们来写一个将移动第1至第3节的方法
- (void) moveSection1ToSection3{
NSMutableArray *section1 = self.arrayOfSection[0];
[self.arrayOfSections removeObject:section1];
[self.arrayOfSections removeObject:section1];
[self.myTableView moveSection:0 toSection:2];
}
我会留给你来决定,当你想调用这个方法,因为我们没能在那一刻对我们的UI中的按钮。你可以简单地创建一个导航控制器,其上放置一个导航按钮,然后调用该方法。
一旦正常运行的应用程序,你会看到部分列队从1到3 ,如图4-12
Figure 4-12. A table view with three sections, each containing three cells
当你调用moveSection1ToSection3方法,你会看到,第1被移动到第3节,第3节移动到第2节的前一个位置,最后第2移动到第1节的前一个位置(图4-13 )
Figure 4-13. Section 1 is moved to Section 3, and other sections are subsequently moved as well
移动单元是非常相似的运动部分。要移动单元格,我们所要做的就是使用moveRowAtIndexPath : toIndexPath :方法。请记住,你可以移动一个单元格从一个部分到同一区段,或到一个新的章节。让我们可以很容易和移动单元1中第1节电池2在同一节,看看会发生什么:
- (void) moveCell1InSection1ToCell2InSection1{
NSMutableArray *section1 = self.arrayOfSection[0];
NSString *cell1InSection1 = section1[0];
[section1 removeObject:cell1InSection1];
[section1 insertObject:cell1InSection1 atIndex:1];
NSIndexPath *sourceIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
NSIndexPath *destinationIndexPath = [NSIndexPath indexPathForRow:1 inSection:0];
[self.myTableView moveAtIndexPath:sourceIndexPath toIndexPath:destinationIndexPath];
}
那么到底是怎么回事这个代码?好了,我们需要确保我们的数据源保持正确的数据需要经过我们四处移动单元格中要显示我们的表视图,所以我们会删除单元格1中第1节第一个。该移动单元2单元1和单元3到单元2 ,共2单元的阵列中。然后,我们将插入电池1到数组的索引1 (第二个对象) 。这将使我们的数组包含cell2,cell1 ,然后cell3 。之后做到这一点,其实我们已提出了细胞在我们的表视图。
让我们把这个有点难度。如何移动单元格2在第1单元1第2节?
- (void) moveCell2InSection1ToCell1InSection2{ NSMutableArray *section1 = self.arrayOfSections[0];
NSMutableArray *section2 = self.arrayOfSections[1]; NSString *cell2InSection1 = section1[1];
[section1 removeObject:cell2InSection1]; [section2 insertObject:cell2InSection1
atIndex:0];
NSIndexPath *sourceIndexPath = [NSIndexPath indexPathForRow:1 inSection:0];
NSIndexPath *destinationIndexPath = [NSIndexPath indexPathForRow:0 inSection:1];
[self.myTableView moveRowAtIndexPath:sourceIndexPath toIndexPath:destinationIndexPath];
}