如何在uitableviewcontroller中动态添加单元格?

时间:2016-06-21 07:10:32

标签: ios objective-c uitableview tableviewcell

有两个textFields的单元格...然后单击ADD按钮我想在tableview中动态添加该单元格。并删除行。 并且在滚动和添加新单元格时,textField上的文本都不会发生变化...

最后我想要在Dictionary的数组中的所有文本字段值。

按照我试过的代码

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

3 个答案:

答案 0 :(得分:2)

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

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

以下是一个示例: 这是快速编写的,只展示来自数据源的动态填充单元格,其他所有内容都不是建议。

#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

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

enter image description here

答案 1 :(得分:1)

我认为你的问题是,在你添加了一个单元格之后,它并没有显示在表格中。在itemArray字典中进行更改后,重新加载tableview的数据。

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

yourTableViewOutlet.reloadData()

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

答案 2 :(得分:0)

插入或删除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];**