在 iOS 開發中,常見的場景是自定義 UITableViewCell 內包含按鈕,點擊按鈕時需要在所屬的 View Controller 中執行具體邏輯(如彈出警報、跳轉頁面等)。由於 Cell 是複用的,且不直接持有 Controller 的引用,直接在 Cell 內調用 Controller 方法並不合適。
通過定義一個協議,讓 Cell 持有弱引用的 delegate,點擊事件觸發時調用 delegate 方法,由 Controller 實現具體業務邏輯。這樣既解耦又符合 MVC 架構。
在 CustomCell.h 中聲明協議與屬性:
@protocol CustomCellDelegate <NSObject>
- (void)showTitle:(NSString *)title;
@end
@interface CustomCell : UITableViewCell
@property (nonatomic, weak) id<CustomCellDelegate> delegate;
@property (nonatomic, strong) IBOutlet UIButton *imageButton;
@property (nonatomic, strong) IBOutlet UILabel *theTitle;
- (IBAction)imageButtonAction;
@end
在 CustomCell.m 中合成 delegate,並在點擊事件中安全調用:
@implementation CustomCell
@synthesize delegate;
- (IBAction)imageButtonAction {
if ([self.delegate respondsToSelector:@selector(showTitle:)]) {
[self.delegate showTitle:self.theTitle.text];
}
}
@end
在 MyViewController.h 中聲明遵循協議:
@interface MyViewController : UIViewController <CustomCellDelegate>
@end
在 MyViewController.m 的 cellForRowAtIndexPath 中設置 delegate:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomCell *cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
cell.delegate = self; // 關鍵:指定當前 Controller 為代理
// 配置 cell 其他內容...
return cell;
}
// 實現協議方法
- (void)showTitle:(NSString *)title {
NSLog(@"The cell title is: %@", title);
// 此處可彈出 Alert、跳轉頁面等
}
採用 Delegate 模式,能優雅解決 Cell 內按鈕事件向外傳遞的問題,是 iOS 開發必備技能。