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

Swift项目:添加图片到收藏页时崩溃或图片不显示求助

问题分析与解决方案

1. 解决初始化崩溃问题

崩溃的核心原因是UICollectionViewController必须通过指定初始化器init(collectionViewLayout:)传入非空布局参数,直接调用无参初始化FavouritesTattooIdeaController()会导致内部的collectionView缺少必要布局配置,触发崩溃。

修复方式:给FavouritesTattooIdeaController添加便捷初始化器

修改FavouritesTattooIdeaController,添加默认配置流式布局的便捷初始化器,同时实现必要的指定初始化器:

class FavouritesTattooIdeaController: UICollectionViewController {

    // 便捷初始化器,默认配置流式布局
    convenience init() {
        let layout = UICollectionViewFlowLayout()
        layout.minimumInteritemSpacing = 1
        layout.minimumLineSpacing = 1
        self.init(collectionViewLayout: layout)
    }

    // 必须实现的指定初始化器
    override init(collectionViewLayout layout: UICollectionViewLayout) {
        super.init(collectionViewLayout: layout)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    // 原有代码...

    override func viewDidLoad() {
        super.viewDidLoad()

        collectionView.backgroundColor = .white
        collectionView.register(FavouritesTattooIdeaCell.self, forCellWithReuseIdentifier: FavouritesTattooIdeaCell.reuseId)
        collectionView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)

        // 移除原来的强制转换layout代码,初始化时已配置完成
        setupEnterLabel()
    }

    // 原有代码...
}

现在调用FavouritesTattooIdeaController()初始化时不会崩溃,同时保留了你需要的布局规则。

2. 解决收藏图片不显示的问题

你当前的代码是创建了一个全新的FavouritesTattooIdeaController实例并添加数据,但这个新实例从未被展示到界面上——用户实际看到的是导航栈中已存在的那个实例,它的photos数组根本没被更新,因此collectionView没有数据可展示。

推荐修复方式:用通知中心传递数据

这种方式不依赖页面结构,灵活性更高:

步骤1:在TattooIdeasViewController中发送通知

修改addBarButtonTapped里的添加动作:

let add = UIAlertAction(title: "Добавить", style: .default) { (action) in
    guard let selectedPhotos = selectedPhotos else { return }
    // 发送通知,携带选中的图片数据
    NotificationCenter.default.post(
        name: NSNotification.Name(rawValue: "AddPhotosToFavorites"),
        object: nil,
        userInfo: ["newPhotos": selectedPhotos]
    )
    
    self.refresh()
}

步骤2:在FavouritesTattooIdeaController中监听通知并更新数据

修改FavouritesTattooIdeaController的viewDidLoad,添加通知监听,并实现处理方法:

override func viewDidLoad() {
    super.viewDidLoad()

    collectionView.backgroundColor = .white
    collectionView.register(FavouritesTattooIdeaCell.self, forCellWithReuseIdentifier: FavouritesTattooIdeaCell.reuseId)
    collectionView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)

    // 添加通知监听
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(handleAddPhotos),
        name: NSNotification.Name(rawValue: "AddPhotosToFavorites"),
        object: nil
    )

    setupEnterLabel()
}

// 处理新增图片的通知
@objc private func handleAddPhotos(_ notification: Notification) {
    guard let newPhotos = notification.userInfo?["newPhotos"] as? [Result] else { return }
    photos.append(contentsOf: newPhotos)
    collectionView.reloadData()
}

// 页面销毁时移除观察者
deinit {
    NotificationCenter.default.removeObserver(self)
}

备选修复方式:查找导航栈中的已有实例

如果FavouritesTattooIdeaController在当前导航栈中,可以直接找到它的实例并更新数据:

let add = UIAlertAction(title: "Добавить", style: .default) { (action) in
    guard let selectedPhotos = selectedPhotos else { return }
    // 从导航栈中查找已存在的收藏页面实例
    if let favVC = self.navigationController?.viewControllers.first(where: { $0 is FavouritesTattooIdeaController }) as? FavouritesTattooIdeaController {
        favVC.photos.append(contentsOf: selectedPhotos)
        favVC.collectionView.reloadData()
    }
    
    self.refresh()
}

这种方式适合导航结构固定的场景,但灵活性不如通知。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 10:15:39