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

Swift按钮图片无法持久化,isComplete状态可正常保存

问题描述

退出并重新进入页面后,isComplete状态可正常保留,但按钮图片无法同步:当isComplete为true时,按钮显示空白圆圈,点击一次会将状态改为false,但图片无变化,仅图片未持久化。

应用逻辑:卡片列表(UITableView)点击进入详情列表,其中5个自定义TaskCell包含任务完成按钮,按钮根据isComplete布尔值(默认false)切换图片,点击时状态会切换,但退出页面后图片不保留。

已自行调试3天仍未解决,恳请提供技术帮助,如需更多信息请告知。


【Card结构体】

import Foundation
import UIKit

struct Task: Codable {
    var text: String?
    var isComplete: Bool
    
    static let sample = Task(text: "One", isComplete: false)
    static let sample2 = Task(text: "Two", isComplete: false)
    static let sample3 = Task(text: "Three", isComplete: false)
    static let sample4 = Task(text: "Four", isComplete: false)
    static let sample5 = Task(text: "Five", isComplete: false)
}

struct Grateful: Codable {
    var text: String?
    
    static let sample = Grateful(text: "One")
    static let sample2 = Grateful(text: "Two")
    static let sample3 = Grateful(text: "Three")
    static let sample4 = Grateful(text: "Four")
}

struct Card: Equatable, Codable {
    var id = UUID()
    var date: Date = Date()
    var tasks: [Task]
    var gratefuls: [Grateful]
    
    static let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
    static let archiveURL = documentsDirectory.appendingPathComponent("cards").appendingPathExtension("plist")
    
    static func ==(lhs: Card, rhs: Card) -> Bool {
        return lhs.id == rhs.id
    }
    
    static func loadCards() -> [Card]?  {
        guard let codedCards = try? Data(contentsOf: archiveURL) else { return nil}
        let propertlyListDecoder = PropertyListDecoder()
        return try? propertlyListDecoder.decode(Array<Card>.self, from: codedCards)
    }
    
    static func saveCards(_ cards: [Card]) {
        let propertlyListEncoder = PropertyListEncoder()
        let codedCards = try? propertlyListEncoder.encode(cards)
        try? codedCards?.write(to: archiveURL, options: .noFileProtection)
    }
    
    static func loadSampleTasks() -> [Card]? {
        let task1 = Card(tasks: [.sample,.sample2,.sample3,.sample4,.sample5], gratefuls: [.sample, .sample2,.sample3,.sample4])
        return [task1]
    }
}

【TaskCell类】

import UIKit

class TaskCell: UITableViewCell {
    @IBOutlet weak var taskBtn: UIButton!
    @IBOutlet weak var taskText: UITextField!
    
    var isComplete: Bool = false
    
    override func awakeFromNib() {
        super.awakeFromNib()
        setButtOnImage()
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
    
    @IBAction func textEditingChanged(_ sender: UITextField) {
        // updateSaveButtonState()
    }
    
    @IBAction func isTaskBtnTapped(_ sender: UIButton) {
        print("Button did get tapped.")
        print(isComplete)
        isComplete.toggle()
        print(isComplete)
        setButtOnImage()
    }
    
    private func setButtOnImage() {
        let buttonImage = isComplete ? "checkmark.circle.fill" : "circle"
        taskBtn.setImage(UIImage(systemName: buttonImage), for: .normal)
    }
}

【Card View Controller】

import UIKit

class CardViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    var card: Card?
    var tasks: Task?
    var gratefuls: Grateful?
    var taskCell = TaskCell()
    var gratefulCell = GratefulCell()
    
    @IBOutlet weak var cardTable: UITableView!
    @IBOutlet weak var saveButton: UIBarButtonItem!
    @IBOutlet weak var cardDateDisplay: UILabel!
    
    @IBAction func saveButtonPressed(_ sender: UIBarButtonItem) {
        let card = readDataFromCells()
        performSegue(withIdentifier: "saveUnwind", sender: card)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.cardTable.register(UINib.init(nibName: "TaskCell", bundle: .main), forCellReuseIdentifier: "TaskCell")
        self.cardTable.register(UINib.init(nibName: "GratefulCell", bundle: .main), forCellReuseIdentifier: "GratefulCell")
        cardTable.separatorStyle = .none
        updateDateDisplay()
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 59
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 9
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if (indexPath.row < 5) {
            let cell:TaskCell = tableView.dequeueReusableCell(withIdentifier: "TaskCell", for: indexPath) as! TaskCell
            let taskIndex = indexPath.row
            if let task = card?.tasks[taskIndex] {
                cell.taskText.text = task.text
                cell.isComplete = task.isComplete
            }
            cell.selectionStyle = .none
            return cell
        } else {
            let cell:GratefulCell = tableView.dequeueReusableCell(withIdentifier: "GratefulCell", for: indexPath) as! GratefulCell
            let gratefulIndex = indexPath.row - (card?.tasks.count ?? 0)
            cell.gratefulNum.text = String(indexPath.row - 4)
            
            if let grateful = card?.gratefuls[gratefulIndex] {
                cell.gratefulText.text = grateful.text
            }
            cell.selectionStyle = .none
            return cell
        }
    }
    
    func updateDateDisplay() {
        let date = Date()
        if let card = card {
            cardDateDisplay.text = card.date.formatted(Date.FormatStyle()
                .weekday(.abbreviated)
                .month(.abbreviated)
                .day(.twoDigits)
                .year(.twoDigits))
        } else {
            cardDateDisplay.text = date.formatted(Date.FormatStyle()
                .weekday(.abbreviated)
                .month(.abbreviated)
                .day(.twoDigits)
                .year(.twoDigits))
        }
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        super.prepare(for: segue, sender: sender)
        guard segue.identifier == "saveUnwind" else { return }
        card = readDataFromCells()
    }
    
    func readDataFromCells() -> Card {
        let numOfRows = cardTable.numberOfRows(inSection: 0)
        var tasks: [Task] = []
        var gratefuls: [Grateful] = []
        for row in 0..<numOfRows {
            let indexPath = IndexPath(row: row, section: 0)
            let cell = cardTable.cellForRow(at: indexPath)
            
            if let cell = cell as? TaskCell {
                let task = Task(text: cell.taskText.text ?? "", isComplete: cell.isComplete)
                tasks.append(task)
            } else if let cell = cell as? GratefulCell {
                let grateful = Grateful(text: cell.gratefulText.text ?? "")
                gratefuls.append(grateful)
            }
        }
        if let card = card {
            print(card)
            return Card(id: card.id, date: card.date, tasks: tasks, gratefuls: gratefuls)
        } else {
            return Card(tasks: tasks, gratefuls: gratefuls)
        }
    }
}

内容的提问来源于stack exchange,提问作者za.ch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 06:25:22