UITableView - 如何在 + 和 - 单击时更新数组?
UITableView - How to update array on + and - click?
我试图达到以下要求:
条件:第一行是强制性的,只有+按钮,其余的都是动态的
+ 和 - 按钮。
即我可以从任何行添加和删除任何行
例如假设我有 4 行,当我从第 2 行单击 + 按钮时,还会有一个
在第 4 行之后添加的行,假设我单击第 3 行的 - 按钮需要删除该行。
我的尝试:
第一次尝试
这是我的代码片段:
ViewDidLoad
dataArray = [[NSMutableArray alloc] init];
for (int i = 0; i < 1; i++)
{
int value = i;
[dataArray addObject: [NSNumber numberWithInt:value]];
}
cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
[cell.serviceAdd addTarget:self action:@selector(onAddServiceButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.serviceRemove addTarget:self action:@selector(onRemoveButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
cell.serviceAdd.tag = indexPath.row;
cell.serviceRemove.tag = indexPath.row;
}
-(void)onAddServiceButtonClicked:(UIButton*)sender
{
//NSLog(@"%ld", (long)sender.tag);
NSNumber *myNum = dataArray.lastObject;
NSNumber *bNumber = [NSNumber numberWithInt:[myNum intValue] + 1];
NSLog(@"%lu", (unsigned long)dataArray.count);
[dataArray addObject:bNumber];
NSLog(@"%lu", (unsigned long)dataArray.count);
[_serviceListTableview reloadData];
}
-(void)onRemoveButtonClicked:(UIButton*)sender
{
NSLog(@"%ld", (long)sender.tag);
NSInteger mySenderValue = sender.tag;
NSNumber *myNum = @(mySenderValue);
NSLog(@"%lu", (unsigned long)dataArray.count);
[dataArray removeObject:myNum];
NSLog(@"%lu", (unsigned long)dataArray.count);
[_serviceListTableview reloadData];
}
上面代码的问题:
我的 dataArray 具有(这些是通过单击 + 按钮的任意行添加的。列表将按顺序排列
仅限订购)
(
0,
1、
2、
3、
4个
)
在此之后,我点击了第二行的 - 按钮,即发件人标签为 1
现在数据数组
(
0,
2、
3、
4个
)
现在我又点击了(价格200)第二行,标签是1
但该条目不会被删除,因为它不在数组中。
第二次尝试:
-(void)onAddServiceButtonClicked:(UIButton*)sender
在这个方法中如果
NSNumber *myNum = dataArray.lastObject;
此行替换为 sender.tag(如在 onRemoveButtonClicked 中实现)
当我单击时,dataArray 中的条目是重复的 - 按钮 2 条目将被删除
任何建议都会对我有很大的帮助。
我认为与其将按钮标签视为数组中的直接数据,不如将它们视为行索引,因为这就是它们的实际含义。因此,您不应使用 removeObject:
来更新数据模型,而应通过传递 tag
值来使用 removeObjectAtIndex:
。
用您的数据而不是索引填充 dataArray。看起来您正在尝试创建某种具有索引和值的 NSDictionary。在您的情况下,根本没有必要。使用 dataArray 作为数据,元素索引将是您的标签。顺便说一句,您可以使用这些函数进行一行更新:
- (void)insertRowsAtIndexPaths: withRowAnimation:
- (void)deleteRowsAtIndexPaths: withRowAnimation:
将方法中的代码:onAddServiceButtonClicked
和 onRemoveButtonClicked
替换为以下代码:
-(void)onAddServiceButtonClicked:(UIButton*)sender
{
NSInteger count = dataArray.count;
NSInteger last = count - 1;
NSInteger newObject = last + 1;
NSLog(@"Count before adding: %lu", (unsigned long)dataArray.count);
[dataArray addObject:[NSNumber numberWithInteger:newObject]];
NSLog(@"Count after adding: %lu", (unsigned long)dataArray.count);
[_serviceListTableview reloadData];
}
-(void)onRemoveButtonClicked:(UIButton*)sender
{
NSInteger position = sender.tag;
NSLog(@"Count before removing row: %lu", (unsigned long)dataArray.count);
[dataArray removeObjectAtIndex:position];
NSLog(@"Count after removing row: %lu", (unsigned long)dataArray.count);
[_serviceListTableview reloadData];
}
希望对您有所帮助。
在标签中使用索引路径本身就很困难,因为当您重新编号行(作为删除行的副作用)时,存储在单元格中的标签变得不正确;所以你需要刷新剩余的行。
比将单元格按钮的操作耦合到 table 视图控制器更好的方法是使用从单元格到 table 视图控制器的委托模式。
我会建议类似
在YourCell.h
@class YourCell;
@protocol YourCellDelegate <NSObject>
@optional -(void) didTapAddInCell:(YourCell *)cell;
@optional -(void) didTapDeleteInCell:(YourCell *)cell;
@end
@interface YourCell : UITableViewCell
@property (weak,nonatomic) id<YourCellDelegate> delegate;
@end
在YourCell.m
- (IBAction)addTapped:(UIButton *)sender {
if ([self.delegate respondsToSelector:@selector(didTapAddInCell:)]) {
[self.delegate didTapAddInCell:self];
}
}
- (IBAction)deleteTapped:(UIButton *)sender {
if ([self.delegate respondsToSelector:@selector(didTapDeleteInCell:)]) {
[self.delegate didTapDeleteInCell:self];
}
}
注意。将 addTapped
和 deleteTapped
设置为按钮的操作处理程序,如果您正在使用原型单元格或单元格初始化程序
然后在您的 table 视图控制器中,在您使单元格出队时设置委托并实现委托方法(您还需要更改 class 定义以表明它实现了协议)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
cell.delegate=self;
...
}
#pragma mark - YourCellDelegate methods
-(void) didTapAddInCell:(YourCell *)cell {
NSIndexPath *newPath=[NSIndexPath indexPathForRow:dataArray.count inSection:0];
NSNumber *myNum = dataArray.lastObject;
NSNumber *bNumber = [NSNumber numberWithInt:[myNum intValue] + 1];
NSLog(@"%lu", (unsigned long)dataArray.count);
[dataArray addObject:bNumber];
NSLog(@"%lu", (unsigned long)dataArray.count);
[_serviceListTableview addRowsAtIndexPaths:@[newPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
-(void) didTapDeleteInCell:(YourCell *)cell {
NSIndexPath *deletedPath=[_serviceListTableView indexPathForCell:cell];
if (deletedPath != nil) {
[dataArray removeObjectAtIndex:deletedPath.row];
[_serviceListTableView deleteRowsAtIndexPaths:@[deletedPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
我试图达到以下要求:
条件:第一行是强制性的,只有+按钮,其余的都是动态的 + 和 - 按钮。
即我可以从任何行添加和删除任何行
例如假设我有 4 行,当我从第 2 行单击 + 按钮时,还会有一个 在第 4 行之后添加的行,假设我单击第 3 行的 - 按钮需要删除该行。
我的尝试:
第一次尝试
这是我的代码片段:
ViewDidLoad
dataArray = [[NSMutableArray alloc] init];
for (int i = 0; i < 1; i++)
{
int value = i;
[dataArray addObject: [NSNumber numberWithInt:value]];
}
cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
[cell.serviceAdd addTarget:self action:@selector(onAddServiceButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.serviceRemove addTarget:self action:@selector(onRemoveButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
cell.serviceAdd.tag = indexPath.row;
cell.serviceRemove.tag = indexPath.row;
}
-(void)onAddServiceButtonClicked:(UIButton*)sender
{
//NSLog(@"%ld", (long)sender.tag);
NSNumber *myNum = dataArray.lastObject;
NSNumber *bNumber = [NSNumber numberWithInt:[myNum intValue] + 1];
NSLog(@"%lu", (unsigned long)dataArray.count);
[dataArray addObject:bNumber];
NSLog(@"%lu", (unsigned long)dataArray.count);
[_serviceListTableview reloadData];
}
-(void)onRemoveButtonClicked:(UIButton*)sender
{
NSLog(@"%ld", (long)sender.tag);
NSInteger mySenderValue = sender.tag;
NSNumber *myNum = @(mySenderValue);
NSLog(@"%lu", (unsigned long)dataArray.count);
[dataArray removeObject:myNum];
NSLog(@"%lu", (unsigned long)dataArray.count);
[_serviceListTableview reloadData];
}
上面代码的问题:
我的 dataArray 具有(这些是通过单击 + 按钮的任意行添加的。列表将按顺序排列 仅限订购) ( 0, 1、 2、 3、 4个 )
在此之后,我点击了第二行的 - 按钮,即发件人标签为 1
现在数据数组
(
0,
2、
3、
4个
)
现在我又点击了(价格200)第二行,标签是1 但该条目不会被删除,因为它不在数组中。
第二次尝试:
-(void)onAddServiceButtonClicked:(UIButton*)sender
在这个方法中如果
NSNumber *myNum = dataArray.lastObject;
此行替换为 sender.tag(如在 onRemoveButtonClicked 中实现)
当我单击时,dataArray 中的条目是重复的 - 按钮 2 条目将被删除
任何建议都会对我有很大的帮助。
我认为与其将按钮标签视为数组中的直接数据,不如将它们视为行索引,因为这就是它们的实际含义。因此,您不应使用 removeObject:
来更新数据模型,而应通过传递 tag
值来使用 removeObjectAtIndex:
。
用您的数据而不是索引填充 dataArray。看起来您正在尝试创建某种具有索引和值的 NSDictionary。在您的情况下,根本没有必要。使用 dataArray 作为数据,元素索引将是您的标签。顺便说一句,您可以使用这些函数进行一行更新:
- (void)insertRowsAtIndexPaths: withRowAnimation:
- (void)deleteRowsAtIndexPaths: withRowAnimation:
将方法中的代码:onAddServiceButtonClicked
和 onRemoveButtonClicked
替换为以下代码:
-(void)onAddServiceButtonClicked:(UIButton*)sender
{
NSInteger count = dataArray.count;
NSInteger last = count - 1;
NSInteger newObject = last + 1;
NSLog(@"Count before adding: %lu", (unsigned long)dataArray.count);
[dataArray addObject:[NSNumber numberWithInteger:newObject]];
NSLog(@"Count after adding: %lu", (unsigned long)dataArray.count);
[_serviceListTableview reloadData];
}
-(void)onRemoveButtonClicked:(UIButton*)sender
{
NSInteger position = sender.tag;
NSLog(@"Count before removing row: %lu", (unsigned long)dataArray.count);
[dataArray removeObjectAtIndex:position];
NSLog(@"Count after removing row: %lu", (unsigned long)dataArray.count);
[_serviceListTableview reloadData];
}
希望对您有所帮助。
在标签中使用索引路径本身就很困难,因为当您重新编号行(作为删除行的副作用)时,存储在单元格中的标签变得不正确;所以你需要刷新剩余的行。
比将单元格按钮的操作耦合到 table 视图控制器更好的方法是使用从单元格到 table 视图控制器的委托模式。
我会建议类似
在YourCell.h
@class YourCell;
@protocol YourCellDelegate <NSObject>
@optional -(void) didTapAddInCell:(YourCell *)cell;
@optional -(void) didTapDeleteInCell:(YourCell *)cell;
@end
@interface YourCell : UITableViewCell
@property (weak,nonatomic) id<YourCellDelegate> delegate;
@end
在YourCell.m
- (IBAction)addTapped:(UIButton *)sender {
if ([self.delegate respondsToSelector:@selector(didTapAddInCell:)]) {
[self.delegate didTapAddInCell:self];
}
}
- (IBAction)deleteTapped:(UIButton *)sender {
if ([self.delegate respondsToSelector:@selector(didTapDeleteInCell:)]) {
[self.delegate didTapDeleteInCell:self];
}
}
注意。将 addTapped
和 deleteTapped
设置为按钮的操作处理程序,如果您正在使用原型单元格或单元格初始化程序
然后在您的 table 视图控制器中,在您使单元格出队时设置委托并实现委托方法(您还需要更改 class 定义以表明它实现了协议)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
cell.delegate=self;
...
}
#pragma mark - YourCellDelegate methods
-(void) didTapAddInCell:(YourCell *)cell {
NSIndexPath *newPath=[NSIndexPath indexPathForRow:dataArray.count inSection:0];
NSNumber *myNum = dataArray.lastObject;
NSNumber *bNumber = [NSNumber numberWithInt:[myNum intValue] + 1];
NSLog(@"%lu", (unsigned long)dataArray.count);
[dataArray addObject:bNumber];
NSLog(@"%lu", (unsigned long)dataArray.count);
[_serviceListTableview addRowsAtIndexPaths:@[newPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
-(void) didTapDeleteInCell:(YourCell *)cell {
NSIndexPath *deletedPath=[_serviceListTableView indexPathForCell:cell];
if (deletedPath != nil) {
[dataArray removeObjectAtIndex:deletedPath.row];
[_serviceListTableView deleteRowsAtIndexPaths:@[deletedPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}