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

时间:2013-04-03 01:35:57

标签: iphone ios uitableview uitextfield

我有一个UITableView,其中有一个自定义原型单元,在另一个类(CustomCell)中定义,其中包含一个UITextField。每次按下按钮,它都会调用一个名为addItem的方法,该方法会创建一个新单元格。我希望UITextFields中的文本转到数组。为了更好地解释它,如果我向UITableView添加3个单元格并在相应的UITextFields中输入3个文本,我希望第1个单元格中的文本转到索引0中的数组,第2个文本转到索引1第三个单元格中的文本转到索引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

4 个答案:

答案 0 :(得分:3)

首先,当您创建每个文本字段时,您自己创建该文本字段的委托,这样您就可以在文本字段中发生某些事情时收到消息。

好的,所以现在当用户键入文本字段时,您将获得消息,并且您可以修改您的模型(数组,您应该将其作为NSMutableArray保留)。但要做到这一点,你需要确定哪个heck单元格包含此消息来自的文本字段!你会做这样的事情:

- (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完成了这类事情(这就是上面代码的来源),所以看看它给你的想法。

答案 1 :(得分:1)

当用户输入完文本后,您可以执行以下操作,将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的可见单元格很可能会使您从屏幕外的单元格中丢失文本并重新使用。

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

答案 2 :(得分:0)

这个问题显然有一些方面。首先,您希望能够恢复对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)以获得正确的行数,并确保在按下+按钮,或者当您尝试更改尚不存在的行的条目时,您可能会遇到异常。

答案 3 :(得分:0)

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