如何在 uitableviewcontroller 中动态添加单元格?
How to add cell dynamically in uitableviewcontroller?
具有两个文本字段的单元格...单击“添加”按钮后,我想在表格视图中动态添加该单元格。并且还删除行。
两个文本字段上的文本在滚动和添加新单元格时不应发生变化...
最后我想要字典数组中的所有文本字段值..
按照我试过的代码
- (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];
}
我认为您的问题是在您添加单元格后,它没有显示在 table 中。在您对 itemArray 字典进行更改后,为您的 table 视图重新加载数据。
在 swift 中看起来像这样,但我相信您将能够在 objective c 中找到相同的代码。
yourTableViewOutlet.reloadData()
每当您将使用的词典更改为 populate/define 您的 table 查看数据时,只需重新加载数据即可。
您的单元格将显示重复的文本字段值,因为您正在重复使用它们而不是调整单元格详细信息,而现在单元格应该代表不同的对象。
如果您不想要这种行为(您显然不想要),那么您需要在数据源上设置单元格详细信息。然后在 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
当我点击添加时,我在滚动时得到以下 table 而没有任何重复:
插入或删除 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];**
具有两个文本字段的单元格...单击“添加”按钮后,我想在表格视图中动态添加该单元格。并且还删除行。 两个文本字段上的文本在滚动和添加新单元格时不应发生变化...
最后我想要字典数组中的所有文本字段值..
按照我试过的代码
- (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];
}
我认为您的问题是在您添加单元格后,它没有显示在 table 中。在您对 itemArray 字典进行更改后,为您的 table 视图重新加载数据。
在 swift 中看起来像这样,但我相信您将能够在 objective c 中找到相同的代码。
yourTableViewOutlet.reloadData()
每当您将使用的词典更改为 populate/define 您的 table 查看数据时,只需重新加载数据即可。
您的单元格将显示重复的文本字段值,因为您正在重复使用它们而不是调整单元格详细信息,而现在单元格应该代表不同的对象。
如果您不想要这种行为(您显然不想要),那么您需要在数据源上设置单元格详细信息。然后在 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
当我点击添加时,我在滚动时得到以下 table 而没有任何重复:
插入或删除 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];**