【问题标题】:Adding a row in TableView iOS在 TableView iOS 中添加一行
【发布时间】:2012-05-31 17:08:20
【问题描述】:

我是 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 的文档以及对以下问题的回答: Add a row dynamically in TableView of iphonehow to properly use insertRowsAtIndexPaths?

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

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

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

非常感谢示例代码,因为我非常沮丧。

顺便说一句,我所做的一切都与进入编辑模式无关,不是吗?

【问题讨论】:

    标签: ios tableview


    【解决方案1】:

    您需要保持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];

    【讨论】:

    • 非常感谢!现在在我看来很明显,但我完全迷失在不同类的文档中,看不到它。
    【解决方案2】:

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

    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];
    }
    

    【讨论】:

    • 谢谢!您对更改 TableView 必须执行的两件事的解释(处理模型,处理表格动画),扩展了前面的两个解释,让我完全理解了这个问题。
    【解决方案3】:

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

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

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

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

    尝试实现这个概念,然后告诉我进展如何。

    【讨论】:

    • 非常感谢!作为第一次尝试,我使用了 trapper 建议的变量,它确实有效,但我的下一步将是按照您的建议使用数组。如果我还有其他问题,我会告诉你。 :)
    【解决方案4】:

    您也可以对 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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-10
      • 1970-01-01
      • 2020-11-28
      • 1970-01-01
      • 2010-12-10
      • 2016-03-16
      相关资源
      最近更新 更多