iOS:从 UITableView 动态添加数据到 NSArray

Posted

技术标签:

【中文标题】iOS:从 UITableView 动态添加数据到 NSArray【英文标题】:iOS: dynamically adding data from UITableView to NSArray 【发布时间】:2013-04-03 01:35:56 【问题描述】:

我有一个 UITableView,其中有一个自定义原型单元格,在另一个类 (CustomCell) 中定义,其中有一个 UITextField。每次我按下按钮时,它都会调用一个名为 addItem 的方法,该方法会创建一个新单元格。我希望 UITextFields 中的文本进入一个数组。为了更好地解释它,如果我向 UITableView 添加 3 个单元格并在相应的 UITextFields 中输入 3 个文本,我希望第一个单元格中的文本进入索引 0 中的数组,第二个单元格中的文本进入索引 1以及第 3 个单元格中的文本到索引 2。我最大的问题是我希望能够回到单元格 1 中的 UITextField 并对其进行更新,并让它动态更新与其对应的 NSArray 对象,即一个在索引 0。我不知道如何处理它。有人可以帮忙吗??? 非常感谢!!

我的代码(obs:itemTable 是 UITableView):

MainViewController.m

@implementation addViewController
    NSInteger n;
    NSString *aid;


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) 
        // Custom initialization
    
    return self;


-(void)viewWillAppear:(BOOL)animated
    n=1;
    aid=@"";


- (void)viewDidLoad

    [super viewDidLoad];
    // Do any additional setup after loading the view.


- (void)didReceiveMemoryWarning

    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

    return 1;



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

    return n;




- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    static NSString *CellIdentifier= @"Cell";

    CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) 
        cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
    

    cell.itemNumber.text=[NSString stringWithFormat:@"Item %d",indexPath.row];

    return cell;


- (IBAction)addItem:(UIButton *)sender 
    ++n;
    [_itemTable reloadData];

- (IBAction)removeItem:(UIButton *)sender 
    if (n>=0)--n;
    [_itemTable reloadData];

CustomCell.m:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier

    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) _itemValue = [[UITextField alloc]init];

        _item = [[UILabel alloc]init];

        [self.contentView addSubview:_itemValue];

        [self.contentView addSubview:_item];

    
    return self;

CustomCell.h

@interface CustomCell : UITableViewCell
@property (strong, nonatomic) IBOutlet UILabel *itemNumber;
@property (strong, nonatomic) IBOutlet UITextField *itemValue;

@end

【问题讨论】:

您是否还在询问如何在按钮操作上添加单元格?否则,请考虑将@matt 标记为正确。 【参考方案1】:

首先,当您创建每个文本字段时,您将自己设置为该文本字段的委托,这样每当文本字段中发生任何事情时您都会收到消息。

好的,所以现在当用户在文本字段中键入时,您将收到消息,并且您可以修改您的模型(数组,我想您应该将其保留为 NSMutableArray)。但要做到这一点,您需要弄清楚哪个单元格包含该消息来自的文本字段!你会这样做:

- (void)textFieldDidEndEditing:(UITextField *)tf 
    // some cell's text field has finished editing; which cell?
    UIView* v = tf;
    do 
        v = v.superview;
     while (![v isKindOfClass: [UITableViewCell class]]);
    CustomCell* cell = (CustomCell*)v;
    // so which row is it?
    NSIndexPath* ip = [self.tableView indexPathForCell:cell];
    //  aha! so now ip.row is the row, and you can update your data model
    //   ... left as an exercise for the reader ...

我在我的书中确实做了这种事情,在 http://www.apeth.com/iosBook/ch21.html#_editable_content_in_table_items(上面的代码来自那里),所以看看它给了你什么想法。

【讨论】:

我可以在 -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 方法中使用它吗?? 在这种情况下探索视图层次结构并不是解决问题的一种非常安全的方法。 tableview 控制器应该负责确定正在编辑哪个单元格并相应地更新数据源。 @BasicallyBits 认为文本委托方法可能是由包含表格的视图控制器实现的。我想走上 superviews 是一种探索,但它怎么可能不安全呢?我们不能指望视图总是被超级视图包含,现在和将来? 你不应该总是依赖 UITextField 来拥有 UITableViewCell 作为它的超级视图之一。这种方法必然是错误的,如果实现发生变化,它会更加脆弱并且容易崩溃。【参考方案2】:

当用户完成输入文本后,您可以执行以下操作,将 tableview 中行的索引路径映射到数组中的索引。

- (NSMutableArray *)updateText 

    NSUInteger cellsCount = [self.tableView numberOfRowsInSection:0];
    NSMutableArray *cellTextArray = [[NSMutableArray alloc] initWithCapacity:cellsCount];

    for(NSInteger i = 0; i < cellsCount; i++) 

        NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
        CustomCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

        NSString *item = cell.itemNumber.text;

        [cellTextArray insertObject:item atIndex:i];
    

    return cellTextArray;

假设您的单元格设置了 UITextFieldDelegate,当用户完成输入文本后,您可以执行以下操作:

- (void)textFieldDidEndEditing:(UITextField *)textField 

    [self.delegate didFinishEditing];

其中self.delegate 是UITableViewController,它会在必要时调用updateText

需要注意的事项 - updateText 中的 for 循环需要遍历 tableview 并为每个索引路径出列单元格。简单地使用 tableview 的可见单元格很可能会让您丢失屏幕外并被重复使用的单元格中的文本。

希望这会有所帮助,祝你好运!

【讨论】:

【参考方案3】:

这个问题显然有几个方面。首先,您希望能够恢复对UILabel 的引用,以便您可以确定特定 UILabel 所在的行。我建议使用tag 属性执行此操作,如下所示:

_item = [[UILabel alloc] init];
_item.tag = 100; // or any value
[self.contentView addSubview:_item];

您还需要设置一个在标签中的文本发生更改时调用的操作。你可以这样做:

[_item addTarget:someObject
          action:@selector(labelChanged:)
forControlEvents:UIControlEventEditingChanged];

无论someObject是什么类,它都需要有一个带有这个签名的方法:

- (void)labelChanged:(id)sender;

在该方法中,您可以检查sender 实际上是UILabel,然后您可以使用sender.text 访问新文本。

为了确定将文本放入数组中的哪个点,您可以在表中的行数上声明一个循环:

for (int i = 0; i < [mainViewControllerInstance tableView:theTableInQuestion numberOfRowsInSection:0]; ++i) 
    if(sender == [[mainViewControllerInstance tableView:theTableInQuestion
                                 cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]] viewWithTag:100]) 
        // Put `sender.text` in the appropriate spot in your array
    

一些补充说明:我会使用NSMutableArray 来跟踪您的字符串,因为您会更新它们,但我不完全确定这里有哪些最佳做法。您还需要确保初始化您的数组(无论您将其设为NSArray 还是NSMutableArray)以获得正确的行数,并确保在+ 按钮时向其中添加行被按下,否则当您尝试更改尚不存在的行的条目时,您可能会遇到异常。

【讨论】:

【参考方案4】:

您可能还想看看免费的 Sensible TableView 框架。该框架几乎可以自动执行您需要的所有操作。应该可以为您节省大量的手工工作。祝你好运!

【讨论】:

以上是关于iOS:从 UITableView 动态添加数据到 NSArray的主要内容,如果未能解决你的问题,请参考以下文章

尝试在用户向 iOS 中的 UITableView 添加行时动态增加 UITableView 的高度

如何使用swift在ios中动态/编程添加多个UITableView? [关闭]

从iOS中的json动态创建UITableView中的UILabels?

从Unix时间戳日期ios数组在Uitableview中创建动态部分?

单击按钮时将单元格动态添加到 UItableview

iOS中UITableView的多列