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
相关产品推荐
相关产品推荐

