iOS - UITableviewCell的子视图不重新加载/更新

Bir*_*rel 1 objective-c subview uitableview reloaddata ios

我有一个表格视图,其中的单元格创建如下:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

    cell.textLabel.text = @"TempTitle";

    cell.textLabel.font = [UIFont fontWithName: @"AppleSDGothicNeo-Bold" size:16.0];

    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];

    UILabel *numberLabel = [[UILabel alloc] init];
    [numberLabel setFrame:CGRectMake(230.0, 5.0, 40.0, 30.0)];
    [numberLabel setText:[NSString stringWithFormat:@"%@", [self.arrayOne objectAtIndex:indexPath.row]]];

    UIButton *buttonDown = [[UIButton alloc] init];
    [buttonDown setFrame:CGRectMake(190.0, 5.0, 40.0, 30.0)];
    buttonDown.tag = indexPath.row;
    [buttonDown addTarget:self action:@selector(quantityDown:) forControlEvents:UIControlEventTouchUpInside];

    UIButton *buttonUp = [[UIButton alloc] init];
    [buttonUp setFrame:CGRectMake(270.0, 5.0, 40.0, 30.0)];

    [cell addSubview:buttonDown];
    [cell addSubview:numberLabel];
    [cell addSubview:buttonUp];

    return cell;
}
Run Code Online (Sandbox Code Playgroud)

where self.arrayOne(此线程的名称已更改)包含每个单元格中显示的整数值.buttonDown选择的方法如下:

- (void) quantityDown:(id)sender {
    int clicked = ((UIButton *)sender).tag;

    ... math to lower int by one and save the new value in arrayOne
    ... this part works just fine. The value does go down, as intended.

    [self.tableView reloadData];
}
Run Code Online (Sandbox Code Playgroud)

当tableView重新加载时,新单元格将打印在该单元格中现有标签的顶部,如下图所示:

屏幕截图

我只能假设新按钮也打印在现有按钮之上.这既昂贵又使得数字不可读(特别是如果你多次改变它!).离开视图并返回到它会干净地显示新数字,但只有在您再次开始更改它们之前.

当我在顶部使用UISegmentedControl时会发生类似的效果.选择一个或另一个会更改表的内容并运行[self.tableView reloadData].调用此方法时,每个单元格的textLabel都会重新加载,但子视图不会重新加载,而是相互堆叠.

我如何写这个,以便每个单元格中只有一个子视图,而不是多个堆叠在一起?快速而且资源不贵的东西.也许删除所有子视图,然后添加新的子视图?我试过类似的东西

[[cell.contentView viewWithTag:tagVariable]removeFromSuperview];
Run Code Online (Sandbox Code Playgroud)

无济于事.实际上,我只需要修改用户点击的表中的一个单元格.除了用户在顶部使用UISegmentedControl时,所有单元格都需要修改.

提前致谢.

编辑1:

创建了一个自定义的UITableViewCell类......

@interface SSCustomTableViewCell : UITableViewCell

@property (nonatomic) UILabel *quantity;
@property (nonatomic) UIButton *down;
@property (nonatomic) UIButton *up;

@end

@implementation SSWeightsTableViewCell

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        self.quantity = [UILabel new];
        [self.contentView addSubview:self.quantity];
        self.down = [UIButton new];
        [self.contentView addSubview:self.down];
        self.up = [UIButton new];
        [self.contentView addSubview:self.up];
    }
    return self;
}

- (void) layoutSubviews {
    [super layoutSubviews];

    [self.down setFrame:CGRectMake(190.0, 5.0, 40.0, 30.0)];
    [self.down setBackgroundColor:[UIColor purpleColor]];

    [self.up setFrame:CGRectMake(270.0, 5.0, 40.0, 30.0)];
    [self.up setBackgroundColor:[UIColor purpleColor]];

    [self.quantity setFrame:CGRectMake(230.0, 5.0, 40.0, 30.0)];
    [self.quantity setTintColor:[UIColor purpleColor]];
}

@end
Run Code Online (Sandbox Code Playgroud)

然后在我的UITableView类中......

#import "SSCustomTableViewCell.h"

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self.tableView
     registerClass:[SSCustomTableViewCell class]
     forCellReuseIdentifier:NSStringFromClass([SSCustomTableViewCell class])
     ];
}
Run Code Online (Sandbox Code Playgroud)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    UITableViewCell *cell = [tableView 
                             dequeueReusableCellWithIdentifier: NSStringFromClass([SSWeightsTableViewCell class])
                             forIndexPath:indexPath
                             ];
}
Run Code Online (Sandbox Code Playgroud)

但现在我所看到的只有以下......

新的节目

子视图未正确布局的位置,也不是正确的大小.此外,在该cellForRowAtIndexPath方法中,我无法访问单元的组件.当我进入

cell.quantity
Run Code Online (Sandbox Code Playgroud)

我收到一条错误,说"在UITableViewCell*类型的对象上找不到"属性'数量'

所以我试过了

SSCustomTableViewCell *cell = [tableView 
                             dequeueReusableCellWithIdentifier: NSStringFromClass([SSWeightsTableViewCell class])
                             forIndexPath:indexPath
                             ];
Run Code Online (Sandbox Code Playgroud)

并且错误消失了,但是当我运行它时它仍然看起来一样.

编辑2:工作解决方案

我所要做的就是添加

cell = [[UITableViewCell alloc]init];
Run Code Online (Sandbox Code Playgroud)

cellForRowAtIndexPath方法内.其他一切都保持不变,不需要自定义类.

dre*_*wag 5

您看到此错误,因为重用了单元实例.如果每次配置单元格时添加视图,则将添加已经包含子视图的单元格.您应该创建自己的UITableViewCell子类,并在init中添加子视图.那么上面的方法只会在各个子视图上设置值.

你的细胞看起来像这样:

@interface MyCustomCell : UITableViewCell

@property (nonatomic, strong) UILabel *myCustomLabel;

@end

@implementation MyCustomCell

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        self.myCustomLabel = [UILabel new];
        [self.contentView addSubview:self.myCustomLabel];
    }
    return self;
}

- (void)layoutSubviews
{
    [super layoutSubviews];

    // Arrange self.myCustomLabel how you want
}

@end
Run Code Online (Sandbox Code Playgroud)

然后您的视图控制器将如下所示:

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self.tableView
        registerClass:[MyCustomCell class]   
        forCellReuseIdentifier:NSStringFromClass([MyCustomCell class])
     ];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView
        dequeueReusableCellWithIdentifier:NSStringFromClass([MyCustomCell class])      
        forIndexPath:indexPath
    ];
    cell.myCustomLabel.text = @"blah";
    return cell;
}
Run Code Online (Sandbox Code Playgroud)