How to add cell dynamically in uitableviewcontroller?

我是研究僧i 提交于 2020-01-06 15:26:49

问题


cell which having two textFields... And on click ADD button I want to add that cell dynamically in tableview. And also delete row. And text on both textField should not get change during scroll and on adding new cell...

And at the end I want all text field value in array of Dictionary..

following the code I have tried

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

回答1:


Your cell will show repeated textfield values because you are reusing them and not adjusting the cell details when a cell is now expected to represent a different object.

If you do not want this behaviour (you obviously don't) then you need to set the cell details on your dataSource. Then in cellForRowAtIndexPath() you populate the current cell with the respective object details. Or, which I do not advise, you can alloc init a new cell in cellForRowAtIndexPath() for each item you add. This will use up more memory unnecessarily when you have cells that are not visible on screen.

Here is an example: this was written quickly to only demonstrate dynamically populating cells from a datasource, everything else is not a suggestion.

#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

When I click add, I get the following table without any repetitions when I scroll:




回答2:


I take it your issue is that after you've added a cell, it doesn't show up in the table. After you make changes in your itemArray dictionary, reload the data for your tableview.

In swift it would look something like this, but I'm sure you'll be able to find the same code in objective c.

yourTableViewOutlet.reloadData()

Whenever you change the dictionary you use to populate/define your tableView data, just reload your data.




回答3:


You should call this when you insert or delete 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];**


来源:https://stackoverflow.com/questions/37937732/how-to-add-cell-dynamically-in-uitableviewcontroller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!