首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

iOS UITableView 傳遞 Cell 資料至 Detail View Controller 完整實作

     編輯:程式設計綜合問答

核心需求

在 UITableView 的 didSelectRowAtIndexPath 中,取得當前選中行對應的模型資料(如電影標題),並傳遞給即將 Push 的 DetailViewController 顯示。

關鍵步驟與代碼

1. 模型層建議:使用具體類型而非 id

// VideoModel.h
@interface VideoModel : NSObject
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *releaseDate;
@property (nonatomic, copy) NSString *posterPath;
@property (nonatomic, copy) NSString *overview;
// 其他欄位...
@end

2. Cell 配置階段:正確綁定模型

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    MovieCell *cell = [tableView dequeueReusableCellWithIdentifier:@"movieCell" forIndexPath:indexPath];
    VideoModel *video = self.model.videos[indexPath.row]; // 強類型
    
    // 日期格式化
    if (video.releaseDate.length) {
        NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
        fmt.dateFormat = @"yyyy-MM-dd";
        NSDate *date = [fmt dateFromString:video.releaseDate];
        fmt.dateFormat = @"MM/yyyy";
        cell.videoDescriptionLabel.text = [NSString stringWithFormat:@"Released: %@", [fmt stringFromDate:date]];
    } else {
        cell.videoDescriptionLabel.text = @"N/A";
    }
    
    cell.videoTitleLabel.text = video.title;
    // 圖片載入...
    return cell;
}

3. 點擊事件:取模型 → 建立目標 VC → 賦值 → Push

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    
    VideoModel *video = self.model.videos[indexPath.row];
    
    UIStoryboard *sb = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    DetailViewController *vc = [sb instantiateViewControllerWithIdentifier:@"DetailVCID"];
    
    // 核心:直接傳遞需要的屬性或整個模型
    vc.movieTitle = video.title;           // 方案 A:傳單一屬性
    vc.videoModel = video;                 // 方案 B:傳整個模型(推薦)
    
    [self.navigationController pushViewController:vc animated:YES];
}

4. DetailViewController 接收與顯示

// DetailViewController.h
@property (nonatomic, copy) NSString *movieTitle;
@property (nonatomic, strong) VideoModel *videoModel;

// DetailViewController.m
- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = self.movieTitle ?: self.videoModel.title;
    // 其餘 UI 綁定...
}

進階優化:使用 Segue 與 prepareForSegue

若在 Storyboard 中已建立 Segue(Identifier: ShowDetail),可簡化為:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [self performSegueWithIdentifier:@"ShowDetail" sender:self.model.videos[indexPath.row]];
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"ShowDetail"]) {
        VideoModel *video = (VideoModel *)sender;
        DetailViewController *vc = segue.destinationViewController;
        vc.videoModel = video;
    }
}

總結

  1. 拒絕使用 id,定義明確模型類別。
  2. 在 didSelectRowAtIndexPath 取模型、建 VC、賦值、Push 四步走。
  3. 優先傳遞完整模型,而非零散屬性,擴充性更強。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved