在 cellForRowAtIndexPath 中直接 addSubview Button,且用 _isAddImageViewLoad 布林旗標控制只加一次。但 UITableView 會重用 Cell,滾動時舊 Cell 被重用,Button 仍留在 ContentView 上,導致位置錯位、重複疊加。
CustomCell : UITableViewCell,在 initWithStyle:reuseIdentifier: 中一次性建立 Button、設定約束/Frame、加入 contentView。configure(with: Model) 方法,根據資料更新 Button 圖片、標題、隱顯狀態。cellForRowAtIndexPath 僅負責取得/建立 Cell 並呼叫 configure。// CustomCell.h
@interface CustomCell : UITableViewCell
@property (nonatomic, strong) UIButton *actionButton;
- (void)configureWithTitle:(NSString *)title showButton:(BOOL)show;
@end
// CustomCell.m
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
_actionButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_actionButton setImage:[UIImage imageNamed:@"AddImage"] forState:UIControlStateNormal];
_actionButton.frame = CGRectMake(110, 10, 110, 110);
[self.contentView addSubview:_actionButton];
}
return self;
}
- (void)configureWithTitle:(NSString *)title showButton:(BOOL)show {
self.textLabel.text = title;
self.actionButton.hidden = !show;
}
// ViewController.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CustomCell" forIndexPath:indexPath];
BOOL showBtn = (indexPath.section == 0 && indexPath.row == 0);
[cell configureWithTitle:itemTitle showButton:showBtn];
return cell;
}
addTarget:action:forControlEvents: 指向 Controller 方法,並在 configure 中設定 tag = indexPath.row 以識別來源。更現代、效能更好、避免手動索引管理錯誤。