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

基于UserDefaults实现iOS表格视图的收藏功能

Hey there! Let’s tackle this UserDefaults persistence problem for your image favorites—no overkill Core Data required. I’ll break this down step by step so it makes total sense.

UserDefaults for Image Favorites Persistence

First, let’s get one key rule straight: never store actual UIImage objects in UserDefaults. It’s designed for lightweight, serializable data like strings, numbers, or arrays of those types. Instead, we’ll store unique identifiers for each image (like a server-provided ID, or the image’s URL as a string) — this keeps things fast and simple.

Step 1: Define a Reusable Key

Start by creating a constant for your UserDefaults key. This avoids typos and makes your code cleaner:

// Add this to a helper file or at the top of your view/controller
private let favoritedImageIDsKey = "FavoritedImageIDs"

Step 2: Handle Favorite Button Taps (Home View)

When a user taps the favorite button, we’ll update a list of saved IDs in UserDefaults. Here’s how to do it in both SwiftUI and UIKit:

SwiftUI Example

Assume you have an ImageModel with a unique id property:

struct ImageCell: View {
    let image: ImageModel
    @State private var isFavorited: Bool = false
    private let userDefaults = UserDefaults.standard

    var body: some View {
        HStack {
            // Your image view here
            Image(uiImage: image.uiImage)
                .resizable()
                .frame(width: 80, height: 80)
            
            Spacer()
            
            Button(action: toggleFavorite) {
                Image(systemName: isFavorited ? "star.fill" : "star")
                    .foregroundColor(isFavorited ? .yellow : .gray)
            }
        }
        .onAppear(perform: loadFavoriteStatus)
    }

    private func loadFavoriteStatus() {
        // Get existing favorite IDs, or an empty array if none exist
        let favoritedIDs = userDefaults.stringArray(forKey: favoritedImageIDsKey) ?? []
        isFavorited = favoritedIDs.contains(image.id)
    }

    private func toggleFavorite() {
        // Get the current list of favorites
        var favoritedIDs = userDefaults.stringArray(forKey: favoritedImageIDsKey) ?? []
        
        if isFavorited {
            // Remove the image from favorites
            favoritedIDs.removeAll { $0 == image.id }
        } else {
            // Add the image to favorites
            favoritedIDs.append(image.id)
        }
        
        // Save the updated list back to UserDefaults
        userDefaults.set(favoritedIDs, forKey: favoritedImageIDsKey)
        // Toggle the button state
        isFavorited.toggle()
    }
}

UIKit Example

For a UITableViewCell with a favorite button:

class ImageTableViewCell: UITableViewCell {
    @IBOutlet weak var favoriteButton: UIButton!
    private let userDefaults = UserDefaults.standard
    private var currentImageID: String = ""

    func configure(with image: ImageModel) {
        currentImageID = image.id
        // Load existing favorite status
        let favoritedIDs = userDefaults.stringArray(forKey: favoritedImageIDsKey) ?? []
        let isFavorited = favoritedIDs.contains(image.id)
        
        // Update button appearance
        favoriteButton.setImage(
            UIImage(systemName: isFavorited ? "star.fill" : "star"), 
            for: .normal
        )
        favoriteButton.tintColor = isFavorited ? .systemYellow : .systemGray
    }

    @IBAction func favoriteTapped(_ sender: UIButton) {
        var favoritedIDs = userDefaults.stringArray(forKey: favoritedImageIDsKey) ?? []
        
        if favoritedIDs.contains(currentImageID) {
            favoritedIDs.removeAll { $0 == currentImageID }
        } else {
            favoritedIDs.append(currentImageID)
        }
        
        userDefaults.set(favoritedIDs, forKey: favoritedImageIDsKey)
        // Refresh button state
        configure(with: ImageModel(id: currentImageID, /* other properties */))
    }
}

Step 3: Load Favorites in Your Collection View

In your favorites tab, fetch the saved IDs and filter your full image list to show only favorited items:

SwiftUI Favorites View

struct FavoritesView: View {
    let allImages: [ImageModel] // Your full list of images
    @State private var favoritedImages: [ImageModel] = []
    private let userDefaults = UserDefaults.standard

    var body: some View {
        List(favoritedImages) { image in
            ImageCell(image: image)
        }
        .onAppear(perform: loadFavorites)
    }

    private func loadFavorites() {
        let favoritedIDs = userDefaults.stringArray(forKey: favoritedImageIDsKey) ?? []
        // Filter full list to only include favorited images
        favoritedImages = allImages.filter { favoritedIDs.contains($0.id) }
    }
}

UIKit Favorites View Controller

class FavoritesViewController: UIViewController {
    @IBOutlet weak var tableView: UITableView!
    let allImages: [ImageModel]
    private var favoritedImages: [ImageModel] = []
    private let userDefaults = UserDefaults.standard

    override func viewDidLoad() {
        super.viewDidLoad()
        loadFavorites()
        tableView.reloadData()
    }

    private func loadFavorites() {
        let favoritedIDs = userDefaults.stringArray(forKey: favoritedImageIDsKey) ?? []
        favoritedImages = allImages.filter { favoritedIDs.contains($0.id) }
    }
}

// Implement UITableViewDataSource methods to display favoritedImages

Key Tips to Avoid Headaches

  • Use unique IDs: Make sure each image has a unique identifier (like a server ID or hashed URL) so you don’t accidentally mix up favorites.
  • Don’t store large data: UserDefaults isn’t for big files — stick to small identifiers only. If you need to save images locally, use the file system instead and store the file paths in UserDefaults.
  • Test edge cases: What if the user has no favorites? The ?? [] operator ensures you always get an empty array instead of nil.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:45:41