【问题标题】:How to add cell dynamically in uitableviewcontroller?如何在 uitableviewcontroller 中动态添加单元格?
【发布时间】:2016-10-22 14:34:01
【问题描述】:

具有两个文本字段的单元格...单击添加按钮时,我想在表格视图中动态添加该单元格。并且还删除行。 在滚动和添加新单元格时,两个 textField 上的文本都不应更改...

最后我想要字典数组中的所有文本字段值..

按照我尝试过的代码

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

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [itemsArray count];
}

-(void) setEditing:(BOOL)editing animated:(BOOL)animated {
    [super setEditing:editing animated:animated];
    [self.tableView setEditing:editing animated:animated];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    AddItemTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"addItemCellIdentifier"];
    if (cell == nil) {
        cell = [[AddItemTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"addItemCellIdentifier"];
    }
    return cell;
}
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {

       [itemsArray removeObjectAtIndex:indexPath.row];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];

- (IBAction)addItemBtnClick:(id)sender {


    if ([itemsArray count]) {
        [itemsArray removeLastObject];
        NSIndexPath *index = [NSIndexPath indexPathForRow:0 inSection:0];
        AddItemTableViewCell *Cell = (AddItemTableViewCell *)[self.tableView cellForRowAtIndexPath:index];
        UITextField * name = (UITextField *)[Cell.contentView viewWithTag:11];
        UITextField * Qty = (UITextField *)[Cell.contentView viewWithTag:12];
        NSMutableDictionary *item = [NSMutableDictionary new];
        [item setObject:name.text forKey:@"item"];
        [item setObject:Qty.text forKey:@"quantity"];
        [itemsArray addObject:item];
    }
    [itemsArray addObject:@{@"item":@"",@"quantity":@""}];
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}

【问题讨论】:

  • 也许这个可以帮助你stackoverflow.com/questions/31870206/…
  • 我已经实现了这个...但是随着单元格数量的增加,默认情况下新的单元格文本字段会被释放单元格值...
  • @AkshayAmbekar 你的数组初始化了吗? itemsArray = [[NSMutableArray alloc] init];
  • 你能说说什么是有效的,以便我们知道我们从哪里开始。如果根本没有显示任何内容,请务必提及。
  • 上面的代码可以动态添加具有两个文本字段的单元格....但是当单元格数量增加并且当我向下和向上滚动时....然后单击添加按钮...新的单元格文本字段不是空白...它包含一些已存在于某些单元格中的值

标签: ios objective-c uitableview tableviewcell


【解决方案1】:

我认为您的问题是添加单元格后,它不会显示在表格中。在对 itemArray 字典进行更改后,重新加载 tableview 的数据。

在 swift 中它看起来像这样,但我相信你将能够在目标 c 中找到相同的代码。

yourTableViewOutlet.reloadData()

每当您更改用于填充/定义 tableView 数据的字典时,只需重新加载您的数据。

【讨论】:

    【解决方案2】:

    您的单元格将显示重复的文本字段值,因为您正在重用它们,而不是在单元格现在应该代表不同的对象时调整单元格详细信息。

    如果您不想要这种行为(显然您不想要),那么您需要在数据源上设置单元格详细信息。然后在 cellForRowAtIndexPath() 中使用相应的对象详细信息填充当前单元格。或者,我不建议,您可以在 cellForRowAtIndexPath() 中为您添加的每个项目分配一个新单元格。当您的单元格在屏幕上不可见时,这会不必要地占用更多内存。

    这是一个例子: 这只是为了演示从数据源动态填充单元格,其他一切都不是建议。

    #import "PeopleTableViewController.h"
    
    //--- Person Class
    @interface Person : NSObject<UITextFieldDelegate>
    @property (nonatomic, strong) NSString *name;
    @property (nonatomic, strong) NSString *surname;
    @end
    @implementation Person
    @end
    //---
    
    #define CELL_HEIGHT 80.0f
    #define TEXTFIELD_HEIGHT 30.0f
    #define TEXTFIELD_WIDTH 120.0f
    #define TEXT_FIELD_VERTICAL_MARGIN (CELL_HEIGHT - (TEXTFIELD_HEIGHT*2)) / 3
    #define TEXT_FIELD_LEFT_MARGIN 20.0f
    //--- Person Cell
    @class PersonCell;
    @protocol  PersonCellTextFieldProtocol <NSObject>
    -(void)personCell: (PersonCell*)cell nameTextfieldDidChange: (NSString*)newText;
    -(void)personCell: (PersonCell*)cell surnameTextfieldDidChange: (NSString*)newText;
    @end
    @interface PersonCell : UITableViewCell<UITextFieldDelegate>
    @property (nonatomic, strong) UITextField *nameTextField;
    @property (nonatomic, strong) UITextField *surnameTextField;
    @property (nonatomic, strong) UILabel *positionLabel;
    @property (nonatomic, assign) id<PersonCellTextFieldProtocol> delegate;
    @end
    @implementation PersonCell
    -(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
    {
        self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
        if(self)
            [self setupSubviews];
        return self;
    }
    -(void)setupSubviews
    {
        NSUInteger nameTextFieldYPosition = TEXT_FIELD_VERTICAL_MARGIN;
    
        self.nameTextField = [[UITextField alloc] initWithFrame: CGRectMake(TEXT_FIELD_LEFT_MARGIN, nameTextFieldYPosition, TEXTFIELD_WIDTH, TEXTFIELD_HEIGHT)];
        self.nameTextField.borderStyle = UITextBorderStyleRoundedRect;
        self.nameTextField.placeholder = @"Name";
        self.nameTextField.delegate = self;
        [self.nameTextField addTarget:self action:@selector(nameTextFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
        [self.contentView addSubview: self.nameTextField];
    
        self.surnameTextField = [[UITextField alloc] initWithFrame: CGRectMake(TEXT_FIELD_LEFT_MARGIN, CGRectGetMaxY(self.nameTextField.frame) + TEXT_FIELD_VERTICAL_MARGIN, TEXTFIELD_WIDTH, TEXTFIELD_HEIGHT)];
        self.surnameTextField.borderStyle = UITextBorderStyleRoundedRect;
        self.surnameTextField.placeholder = @"Surname";
        self.surnameTextField.delegate = self;
        [self.surnameTextField addTarget:self action:@selector(surnameTextFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
        [self.contentView addSubview: self.surnameTextField];
    
        self.positionLabel = [[UILabel alloc] initWithFrame: CGRectMake(5, 0, 10, 20)];
        self.positionLabel.font = [UIFont systemFontOfSize: 10];
        [self.contentView addSubview: self.positionLabel];
        self.positionLabel.center = CGPointMake(self.positionLabel.center.x, self.contentView.center.y);
    }
    
    -(void)layoutSubviews
    {
        self.positionLabel.center = CGPointMake(self.positionLabel.center.x, self.contentView.center.y);
    }
    
    -(void)nameTextFieldDidChange:(UITextField*)textField
    {
        if([self.delegate respondsToSelector: @selector(personCell:nameTextfieldDidChange:)])
            [self.delegate personCell:self nameTextfieldDidChange:textField.text];
    }
    
    -(void)surnameTextFieldDidChange:(UITextField*)textField
    {
        if([self.delegate respondsToSelector: @selector(personCell:surnameTextfieldDidChange:)])
            [self.delegate personCell:self surnameTextfieldDidChange:textField.text];
    }
    
    -(BOOL)textFieldShouldReturn:(UITextField *)textField
    {
        [textField resignFirstResponder];
        return YES;
    }
    @end
    //---
    
    @interface PeopleTableViewController ()<PersonCellTextFieldProtocol>
    @end
    
    @implementation PeopleTableViewController
    {
        NSMutableArray *_peopleArray;
    }
    
    -(void)viewDidLoad
    {
        _peopleArray = [[NSMutableArray alloc] init];
        [self.tableView reloadData];
    }
    
    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        PersonCell *cell = nil;
        cell = [tableView dequeueReusableCellWithIdentifier: @"CellWithNameAndSurname"];
        if(!cell)
        {
            cell = [[PersonCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CellWithNameAndSurname"];
            cell.contentView.backgroundColor = [[UIColor blueColor] colorWithAlphaComponent: 0.08f];
            cell.delegate = self;
        }
    
        //this should be outside the above if statement!
        Person *respectivePerson = _peopleArray[indexPath.row];
        cell.nameTextField.text = respectivePerson.name;
        cell.surnameTextField.text = respectivePerson.surname;
        cell.positionLabel.text = [NSString stringWithFormat:@"%i", (int)indexPath.row];
    
        return cell;
    }
    
    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        return CELL_HEIGHT;
    }
    
    -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        return 1;
    }
    
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return _peopleArray.count;
    }
    
    -(void)personCell:(PersonCell *)cell nameTextfieldDidChange:(NSString *)newText
    {
        Person *respectivePerson = _peopleArray[[self.tableView indexPathForCell: cell].row];
        respectivePerson.name = newText;
    }
    
    -(void)personCell:(PersonCell *)cell surnameTextfieldDidChange:(NSString *)newText
    {
        Person *respectivePerson = _peopleArray[[self.tableView indexPathForCell: cell].row];
        respectivePerson.surname = newText;
    }
    
    - (IBAction)addItemBtnClick:(id)sender
    {
        Person *newPerson = [Person new];
    
        [_peopleArray addObject: newPerson];
    
        [self.tableView reloadData];
    }
    
    @end
    

    当我点击添加时,我滚动时得到下表,没有任何重复:

    【讨论】:

    • 我试图从 cellForRowAtIndexPath() 中的数据源填充单元格...但随后单元格获取随机值并且仍然出现问题。你能建议我其他选择吗?请告诉我如何为每个项目分配初始化新单元格 cellForRowAtIndexPath?
    • @AkshayAmbekar 看看我刚刚添加的示例。继续询问您是否不确定。
    • @AkshayAmbekar 查看更新。这对我来说很好。
    • 它现在可以工作了......但是我怎样才能获得 textFields 值? @pnizzle
    • @AkshayAmbekar 如果对您有帮助,请将其标记为正确答案。这个例子(上面)展示了如何获取文本字段值并将它们存储在一个人对象中,在你的情况下是一个字典
    【解决方案3】:

    你应该在插入或删除 UITableViewCell 时调用它:

    **[self.tableView beginUpdates];**
    if ([itemsArray count]) {
    [itemsArray removeLastObject];
    NSIndexPath *index = [NSIndexPath indexPathForRow:0 inSection:0];
    AddItemTableViewCell *Cell = (AddItemTableViewCell *)[self.tableView cellForRowAtIndexPath:index];
    UITextField * name = (UITextField *)[Cell.contentView viewWithTag:11];
    UITextField * Qty = (UITextField *)[Cell.contentView viewWithTag:12];
    NSMutableDictionary *item = [NSMutableDictionary new];
    [item setObject:name.text forKey:@"item"];
    [item setObject:Qty.text forKey:@"quantity"];
    [itemsArray addObject:item];
    
    }
    [itemsArray addObject:@{@"item":@"",@"quantity":@""}];
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
    
    **[self.tableView endUpdates];**
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-13
      • 2014-12-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多