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

Swift 4中实现「添加至收藏」及收藏列表展示方案咨询

实现TableView图片收藏功能的分步指南(Swift 4)

嘿,作为Swift 4新手能想到做带收藏功能的TableView应用已经超棒啦!我给你一步步拆解这个需求,每一步都尽量用简单易懂的代码和说明,保证你能跟上~

1. 先定义统一的图片数据模型

首先我们需要一个结构化的模型来存储图片信息,这样主页面和收藏页面都能方便地传递、展示数据:

import UIKit

// 图片数据模型,兼容本地/网络图片
class ImageItem: NSObject {
    var image: UIImage?
    var imageIdentifier: String? // 用唯一标识区分图片(本地图用名称,网络图用URL)
    
    // 初始化方法
    init(image: UIImage?, identifier: String?) {
        self.image = image
        self.imageIdentifier = identifier
    }
}

2. 用单例管理共享收藏数据(核心!)

要让两个视图控制器共享收藏数据,单例是最适合新手的方案——它能保证整个APP里只有一个收藏数据实例,两边都能读写:

class FavoriteManager {
    // 全局唯一的单例实例
    static let shared = FavoriteManager()
    
    // 存储收藏图片的数组
    var favoriteImages: [ImageItem] = []
    
    // 私有初始化方法,防止外部创建新实例
    private init() {}
    
    // 添加收藏:先判断是否已收藏,避免重复添加
    func addToFavorite(item: ImageItem) {
        guard let id = item.imageIdentifier, 
              !favoriteImages.contains(where: { $0.imageIdentifier == id }) else {
            return
        }
        favoriteImages.append(item)
    }
    
    // 可选:移除收藏的方法(以后需要的话可以用)
    func removeFromFavorite(item: ImageItem) {
        if let index = favoriteImages.firstIndex(where: { $0.imageIdentifier == item.imageIdentifier }) {
            favoriteImages.remove(at: index)
        }
    }
}

3. 主页面TableView单元格配置

假设你用Storyboard搭建了主页面单元格,里面包含UIImageView和「添加至收藏」按钮,记得给它们添加IBOutlet关联:

import UIKit

class MainTableViewCell: UITableViewCell {
    @IBOutlet weak var itemImageView: UIImageView!
    @IBOutlet weak var favoriteButton: UIButton!
    
    // 保存当前单元格对应的图片数据
    var currentItem: ImageItem?
    
    override func awakeFromNib() {
        super.awakeFromNib()
        // 给按钮绑定点击事件
        favoriteButton.addTarget(self, action: #selector(favoriteButtonTapped), for: .touchUpInside)
        // 初始化按钮状态
        favoriteButton.setTitle("添加至收藏", for: .normal)
    }
    
    // 按钮点击逻辑
    @objc func favoriteButtonTapped() {
        guard let item = currentItem else { return }
        // 调用单例的收藏方法
        FavoriteManager.shared.addToFavorite(item: item)
        // 更新按钮状态,提示用户已收藏
        favoriteButton.setTitle("已收藏", for: .normal)
        favoriteButton.isEnabled = false // 禁用按钮防止重复点击
    }
    
    // 配置单元格数据的方法
    func configure(with item: ImageItem) {
        currentItem = item
        itemImageView.image = item.image
        // 可选:判断图片是否已收藏,设置按钮初始状态
        let isFavorited = FavoriteManager.shared.favoriteImages.contains(where: { $0.imageIdentifier == item.imageIdentifier })
        if isFavorited {
            favoriteButton.setTitle("已收藏", for: .normal)
            favoriteButton.isEnabled = false
        } else {
            favoriteButton.setTitle("添加至收藏", for: .normal)
            favoriteButton.isEnabled = true
        }
    }
}

然后在主页面的ViewController里,给TableView设置数据源(假设你已经有了主页面的图片数组mainImages: [ImageItem]):

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "MainTableViewCell", for: indexPath) as! MainTableViewCell
    let item = mainImages[indexPath.row]
    cell.configure(with: item)
    return cell
}

4. 收藏页面的实现

接下来是收藏页面的ViewController,同样用TableView展示收藏的图片:

先创建收藏页面的单元格(只需要展示图片,不需要按钮):

import UIKit

class FavoriteTableViewCell: UITableViewCell {
    @IBOutlet weak var favoriteImageView: UIImageView!
    
    func configure(with item: ImageItem) {
        favoriteImageView.image = item.image
    }
}

然后在收藏页面的ViewController里,保证每次页面出现时加载最新的收藏数据:

import UIKit

class FavoriteViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    @IBOutlet weak var favoriteTableView: UITableView!
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        // 每次页面显示时重新加载数据,确保展示最新收藏
        favoriteTableView.reloadData()
    }
    
    // MARK: - TableView 数据源方法
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return FavoriteManager.shared.favoriteImages.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "FavoriteTableViewCell", for: indexPath) as! FavoriteTableViewCell
        let item = FavoriteManager.shared.favoriteImages[indexPath.row]
        cell.configure(with: item)
        return cell
    }
}

5. 可选:让收藏数据持久化(重启APP不丢失)

如果希望用户重启APP后收藏的图片还在,可以用UserDefaults存储图片的唯一标识(不要直接存UIImage,效率低),修改FavoriteManager的代码:

class FavoriteManager {
    static let shared = FavoriteManager()
    var favoriteImages: [ImageItem] = []
    private let defaultsKey = "SavedFavoriteImages"
    
    private init() {
        // 初始化时从UserDefaults加载数据
        loadSavedFavorites()
    }
    
    func addToFavorite(item: ImageItem) {
        guard let id = item.imageIdentifier, 
              !favoriteImages.contains(where: { $0.imageIdentifier == id }) else {
            return
        }
        favoriteImages.append(item)
        // 保存到UserDefaults
        saveFavorites()
    }
    
    // 保存收藏数据到本地
    private func saveFavorites() {
        let identifiers = favoriteImages.compactMap { $0.imageIdentifier }
        UserDefaults.standard.set(identifiers, forKey: defaultsKey)
    }
    
    // 从本地加载收藏数据
    private func loadSavedFavorites() {
        if let identifiers = UserDefaults.standard.array(forKey: defaultsKey) as? [String] {
            // 这里需要你根据标识重新加载图片(本地图用名称,网络图用URL下载)
            favoriteImages = identifiers.map { 
                ImageItem(image: loadImage(from: $0), identifier: $0) 
            }
        }
    }
    
    // 自定义方法:根据标识加载图片
    private func loadImage(from identifier: String) -> UIImage? {
        // 本地图片:return UIImage(named: identifier)
        // 网络图片需要用URLSession下载,这里就不展开啦
        return UIImage(named: identifier)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 16:37:58