You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delegate失效:点击Cell后数据无法传递至详情ViewController

问题分析与修复方案

核心问题

  1. Delegate赋值逻辑错误:你在DetailsViewController的viewDidLoad里新建了一个LibraryVC实例并设置代理,但这个新实例和当前展示CollectionView的LibraryVC是完全独立的对象,导致原LibraryVC的movieDelegate始终为nil,调用代理方法时无响应。
  2. 图片加载方式错误:UIImage(named:)仅用于加载本地资源图片,而你传入的是网络图片URL字符串,无法通过这种方式加载网络图片。

修复步骤

方案一:直接传值(推荐,逻辑更直观)

修改LibraryVC的didSelectItemAt方法

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    guard let movieItem = dataSource.itemIdentifier(for: indexPath) else {
        return
    }
    print(movieItem.image.original)
    
    // 创建详情VC并直接传递图片URL
    let detailsVC = DetailsViewController()
    detailsVC.movieImageUrlString = movieItem.image.original
    
    let navController = UINavigationController(rootViewController: detailsVC)
    present(navController, animated: true)
}

修改DetailsViewController代码

// 新增存储图片URL的属性
var movieImageUrlString: String?

override func viewDidLoad() {
    super.viewDidLoad()
    // 删除原来新建LibraryVC的无效代码
    
    // 加载网络图片
    guard let urlString = movieImageUrlString, let url = URL(string: urlString) else {
        return
    }
    
    URLSession.shared.dataTask(with: url) { [weak self] data, _, error in
        guard let data = data, error == nil else { return }
        // 回到主线程更新UI
        DispatchQueue.main.async {
            self?.movieImage.image = UIImage(data: data)
        }
    }.resume()
}

// 删除无用的Delegate扩展

方案二:修正Delegate使用方式(不推荐,没必要绕弯)

修改LibraryVC的didSelectItemAt方法

// 先把代理属性改成可选类型,避免强制解包崩溃
var movieDelegate: LibraryVCDelegate?

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    guard let movieItem = dataSource.itemIdentifier(for: indexPath) else {
        return
    }
    
    let detailsVC = DetailsViewController()
    // 将当前LibraryVC的代理设置为详情VC
    self.movieDelegate = detailsVC
    
    let navController = UINavigationController(rootViewController: detailsVC)
    present(navController, animated: true)
    
    // 调用代理方法
    movieDelegate?.didGetMovie(moive: movieItem.image.original)
}

修改DetailsViewController代码

override func viewDidLoad() {
    super.viewDidLoad()
    // 删除原来新建LibraryVC的无效代码
}

extension DetailsViewController: LibraryVCDelegate {
    func didGetMovie(moive: String) {
        // 改用网络加载图片
        guard let url = URL(string: moive) else { return }
        URLSession.shared.dataTask(with: url) { [weak self] data, _, error in
            guard let data = data, error == nil else { return }
            DispatchQueue.main.async {
                self?.movieImage.image = UIImage(data: data)
            }
        }.resume()
    }
}

额外提示

  • 网络图片加载建议使用第三方库(如Kingfisher、SDWebImage),自带缓存、错误处理等功能,比手写URLSession更稳定。
  • 避免用!强制解包可选类型,改用?可选链式调用,防止nil崩溃。

内容的提问来源于stack exchange,提问作者Ethan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 22:43:12