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

