如何正确使用insertRowsAtIndexPaths?

时间:2011-08-04 14:44:07

标签: iphone objective-c xcode uitableview

我在线浏览了所有示例,无法弄清楚如何使用动画正确添加单元格到tableview。假设我有一个部分有一个单元格,我想在用户点击第一个单元格的附件后添加另一个单元格。

我的“添加”方法执行此操作:

- (IBAction) toggleEnabledTextForSwitch1onSomeLabel: (id) sender {  
if (switch1.on) {

    NSArray *appleComputers = [NSArray arrayWithObjects:@"WWWWW" ,@"XXXX", @"YYYY", @"ZZZZ", nil];
    NSDictionary *appleComputersDict = [NSDictionary dictionaryWithObject:appleComputers forKey:@"Computers"];
    [listOfItems replaceObjectAtIndex:0 withObject:appleComputersDict];
    [tblSimpleTable reloadData];

}

哪个有效,但没有动画。我知道为了添加动画,我需要使用insertRowsAtIndexPaths:withRowAnimation,所以我尝试了很多选项但是在执行insertRowsAtIndexPaths:withRowAnimation方法时它总是崩溃。

我最近的尝试是这样做的:

- (IBAction) toggleEnabledTextForSwitch1onSomeLabel: (id) sender {  
if (switch1.on) {

    NSIndexPath *path1 = [NSIndexPath indexPathForRow:1 inSection:0]; //ALSO TRIED WITH indexPathRow:0
      NSArray *indexArray = [NSArray arrayWithObjects:path1,nil];   
     [tblSimpleTable insertRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationRight];

}
}  

我做错了什么?我怎样才能轻松实现这一目标?我不明白这整个indexPathForRow的事情......我也不明白如何使用这种方法我可以为新单元格添加标签名称。请帮忙......谢谢!!

5 个答案:

答案 0 :(得分:23)

这是一个两步过程:

首先更新您的数据源,以便numberOfRowsInSectioncellForRowAtIndexPath为您的插入后数据返回正确的值。您必须在插入或删除行之前执行此操作,否则您将看到“无效行数”错误。

然后插入你的行:

[tblSimpleTable beginUpdates];
[tblSimpleTable insertRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationRight];
[tblSimpleTable endUpdates];

简单地插入或删除行不会改变您的数据源;你必须自己做。

答案 1 :(得分:22)

使用insertRowsAtIndexPaths时要记住的重要一点是,UITableViewDataSource需要匹配插件告诉它的内容。如果向表视图添加行,请确保已更新后备数据以匹配。

答案 2 :(得分:6)

首先,您应该在更新表本身之前更新数据模型。 您也可以使用:

[tableView beginUpdates];
// do all row insertion/delete here
[tableView endUpdates];

表格会立即生成所有动画(如果你指定的话)

答案 3 :(得分:2)

insertRowsAtIndexPaths:withRowAnimation:以及数据模型的更改都需要在 beginUpdatesendUpates

之间进行

我创建了一个应该独立工作的简单示例。因为找不到任何简单的例子,我花了一周的时间来解决这个问题,所以我希望这能节省时间和头痛!

@interface MyTableViewController ()
@property (nonatomic, strong) NSMutableArray *expandableArray;
@property (nonatomic, strong) NSMutableArray *indexPaths;
@property (nonatomic, strong) UITableView *myTableView;
@end

@implementation MyTableViewController

- (void)viewDidLoad
{
    [self setupArray];
}

- (void)setupArray
{
    self.expandableArray = @[@"One", @"Two", @"Three", @"Four", @"Five"].mutableCopy;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.expandableArray.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //here you should create a cell that displays information from self.expandableArray, and return it
}

//call this method if your button/cell/whatever is tapped
- (void)didTapTriggerToChangeTableView
{
    if (/*some condition occurs that makes you want to expand the tableView*/) {
        [self expandArray]
    }else if (/*some other condition occurs that makes you want to retract the tableView*/){
        [self retractArray]
    }
}

//this example adds 1 item
- (void)expandArray
{
    //create an array of indexPaths
    self.indexPaths = [[NSMutableArray alloc] init];
    for (int i = theFirstIndexWhereYouWantToInsertYourAdditionalCells; i < theTotalNumberOfAdditionalCellsToInsert + theFirstIndexWhereYouWantToInsertYourAdditionalCells; i++) {
        [self.indexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
    }

    //modify your array AND call insertRowsAtIndexPaths:withRowAnimation: INBETWEEN beginUpdates and endUpdates
    [self.myTableView beginUpdates];
    //HERE IS WHERE YOU NEED TO ALTER self.expandableArray to have the additional/new data values, eg:
    [self.expandableArray addObject:@"Six"];
    [self.myTableView insertRowsAtIndexPaths:self.indexPaths withRowAnimation:(UITableViewRowAnimationFade)];  //or a rowAnimation of your choice

    [self.myTableView endUpdates];
}

//this example removes all but the first 3 items
- (void)retractArray
{
    NSRange range;
    range.location = 3;
    range.length = self.expandableArray.count - 3;

    //modify your array AND call insertRowsAtIndexPaths:withRowAnimation: INBETWEEN beginUpdates and endUpdates
    [self.myTableView beginUpdates];
    [self.expandableArray removeObjectsInRange:range];
    [self.myTableView deleteRowsAtIndexPaths:self.indexPaths withRowAnimation:UITableViewRowAnimationFade];  //or a rowAnimation of your choice
    [self.myTableView endUpdates];
}

@end

答案 4 :(得分:0)

对于快速用户

// have inserted new item into data source

// update
self.tableView.beginUpdates()
var ip = NSIndexPath(forRow:find(self.yourDataSource, theNewObject)!, inSection: 0)
self.tableView.insertRowsAtIndexPaths([ip], withRowAnimation: UITableViewRowAnimation.Fade)
self.tableView.endUpdates()