8

我对 iOS 开发很陌生,尝试一些应该很容易的事情让我度过了一段糟糕的时光;每次用户单击现有行之一时,在 TableView 中添加额外的行。该操作没有真正的目的,我只是想了解 TableView 的行为。

所以我做了以下事情:

我使用了基于拆分视图的模板,并将 RootViewController 中的行数更改为 30。

- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section {
   // Return the number of rows in the section.
   return 30;
}

方法 tableView:didSelectRowAtIndexPath 看起来如下:

- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    /*
    When a row is selected, set the detail view controller's detail item to the item associated with the selected row.
    */
   NSMutableArray* paths = [[NSMutableArray alloc] init];
   NSIndexPath *indice = [NSIndexPath indexPathForRow:30 inSection:0];
   [paths addObject:indice];
   detailViewController.detailItem = [NSString stringWithFormat:@"Second Story Element %d with all its information and bla bla bla", indexPath.row];
   [[self tableView] beginUpdates];
   [self.tableView insertRowsAtIndexPaths:(NSArray *) paths withRowAnimation:UITableViewRowAnimationNone];
   [[self tableView] endUpdates];
}

当我执行程序并单击其中一个元素时,我收到以下错误:

*** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无效更新:第 0 节中的行数无效。更新后现有节中包含的行数 (30) 必须等于行数更新前包含在该节中 (30),加上或减去从该节插入或删除的行数(插入 1,删除 0)。

我没有更改模板提供的代码的任何其他部分。

我非常广泛地阅读了 Apple 的文档以及对以下问题的回答: 在 iphone 的 TableView 中动态添加一行 以及 如何正确使用 insertRowsAtIndexPaths?

第二个问题似乎解决了同样的问题,但我无法理解发生了什么。它们对数据源意味着什么?我更好理解的回应如下:

这是一个两步过程:首先更新您的数据源,以便 numberOfRowsInSection 和 cellForRowAtIndexPath 将为您的插入后数据返回正确的值。您必须在插入或删除行之前执行此操作,否则您将看到“无效的行数”错误。

数据源的这种更新意味着什么?

示例代码将不胜感激,因为我非常沮丧。

顺便说一句,我正在尝试的所有内容都与进入编辑模式无关,不是吗?

4

4 回答 4

14

您需要保持tableView:numberOfRowsInSection:同步返回的计数!

因此,当您有 30 行然后告诉 tableview 插入新行时,您需要确保tableView:numberOfRowsInSection:现在返回 31。

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

- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
   self.rowCount++;

   [self.tableView beginUpdates];
   [self.tableView insertRowsAtIndexPaths:(NSArray *) paths withRowAnimation:UITableViewRowAnimationNone];
   [self.tableView endUpdates];
}

在实践中,您可能会使用数组来跟踪您的行return [self.rows count];

于 2012-05-31T17:12:15.317 回答
3

答案很简单。当您想要修改表格视图时,您需要执行两个简单的步骤:

  1. 处理模型
  2. 处理表格动画

您已经执行了第二步。但是你错过了第一个。通常,当您处理一个表时,您会将一个数据源传递给它。换句话说,要在其中显示一些数据。

一个简单的示例是使用NSMutableArray包含虚拟数据的(顾名思义是动态的)。

例如,在 .h 中创建如下所示的属性

@property (nonatomic, strong) NSMutableArray* myDataSource;

并在 .m 中将其合成为:

@synthesize myDataSource;

现在,您可以alloc-init使用该数组并将其填充如下(例如在viewDidLoad控制器的方法中)。

self.myDataSource = [[NSMutableArray alloc] init];
[self.myDataSource addObject:@"First"];
[self.myDataSource addObject:@"Second"];

然后,您可以执行以下操作,而不是硬编码您将显示的行数(在您的情况下为 30):

- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section    {

   return [self.myDataSource count];
}

现在,在您的didSelectRowAtIndexPath委托中,您可以添加第三个元素。

- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

   [self.myDataSource addObject:@"Third"];

   [[self tableView] beginUpdates];
   [self.tableView insertRowsAtIndexPaths:(NSArray *) paths withRowAnimation:UITableViewRowAnimationNone];
   [[self tableView] endUpdates];
}
于 2012-05-31T17:26:51.670 回答
2

看起来一个大问题是tableView:numberOfRowsInSection:. 您需要在该方法中返回正确的行数。

为此,通常最好为表格视图维护一个NSArrayNSMutableArray多个项目,因此在该函数中,您可以说:return [arrayOfValues count];. 将数组保留为视图控制器类的属性,以便在所有方法中都可以轻松访问它。

该数组也可以用于cellForRowAtIndexPath:. 如果你有一个数组NSString,你可以说cell.text = [arrayOfValues objectAtRow:indexPath.row];

然后,当您想将项目添加到表格视图时,您可以将其添加到数组并重新加载表格,例如[tableView reloadData];.

尝试实现这个概念,让我知道它是如何进行的。

于 2012-05-31T17:12:28.067 回答
0

您也可以对 dayanamic 表格单元格执行此操作

    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
        {
            return [arrayStationStore count];
        }
        -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
        {
            static NSString *cellIndentyfire;
            UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIndentyfire];
            if (cell ==  nil)
            {
                cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIndentyfire];


            }



            cell.textLabel.text = [arrayStationStore objectAtIndex:indexPath.row];
            return cell;
        }

-(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Check if current row is selected
    BOOL isSelected = NO;
    if([tblStationName cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryCheckmark)
    {
        isSelected = YES;
    }

    if(isSelected)
    {
        [tblStationName cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
        [arrayReplace removeObject:indexPath];
        NSLog(@"array replace remove is %@ ",arrayReplace);
    }
    else
    {
        [tblStationName cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
        [arrayReplace addObject:indexPath];
         NSLog(@"array replace add is %@ ",arrayReplace);
    }
    return indexPath;
}
于 2014-10-07T15:05:11.843 回答