swift - 如何在本地保存数组数据
问题描述
这是我的代码。我想学习如何为每个单元格的like 按钮保存我的数据源。这样当用户离开应用程序并稍后返回时,被喜欢的相同单元格仍然被喜欢。
这是我上一篇文章的新代码。由于我不想继续制作新数组,因此我可以尝试在本地保存我的 dataSource 变量,该变量存储每个单元格的被喜欢与否的状态。
视图控制器 -
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet var tableView: UITableView!
var dataSource: [TableModel] = []
var updatedCell = TableViewCell()
var updatedIndex = Int()
override func viewDidLoad() {
super.viewDidLoad()
overrideUserInterfaceStyle = .light
self.dataSource = Array(repeating: TableModel(isLiked: false), count: 8)
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.showsVerticalScrollIndicator = false
self.tableView.reloadData()
}
@IBAction func buttonSelected(_ sender: Any) {
// Update Cell for which UIButton (Like Button) was tapped.
dataSource[(sender as AnyObject).tag].isLiked = !dataSource[(sender as AnyObject).tag].isLiked
let indexPath = IndexPath(row: (sender as AnyObject).tag, section: 0)
tableView.reloadRows(at: [indexPath], with: .automatic)
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
// Saved updatedCell & updatedIndex variables for delegate pattern. To Update this VC's cells data when edited on secondVC (moreInfoViewController) in a way, made them accessible outside this function
// To Get Specific TableView Cell the user is interacting with.
updatedCell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
updatedIndex = indexPath.row
// Go to Second VC and Send cell tapped data to next view
let vc = (storyboard?.instantiateViewController(identifier: "secondVC") as? moreInfoViewController)!
vc.delegate = self
// Get Status of Liked Button in the cell the user tapped and display if the user liked it previously in the SecondVC
let isLiked = dataSource[indexPath.row].isLiked
if isLiked {
// print("Liked")
vc.isLiked = true
} else {
// print("Not Liked")
vc.isLiked = false
}
present(vc, animated: true)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 8
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
// cell.moreBtn.isUserInteractionEnabled = false
cell.likeBtn.tag = indexPath.row
// cell.likeBtn.addTarget(self, action: #selector(buttonSelected(_:)), for: .touchUpInside)
// Get Each Cell Liked Button Status and display if the user liked or not Liked each cell
let isLiked = dataSource[indexPath.row].isLiked
if isLiked {
// User liked the post
cell.likeBtn.setImage(UIImage(named: "liked"), for: UIControl.State.normal)
} else {
// User Unliked the post
cell.likeBtn.setImage(UIImage(named: "unLiked"), for: UIControl.State.normal)
}
return cell
}
}
// Conform VC to protocol (VC2Delegate) located in "Structs.swift" File
extension ViewController: VC2Delegate {
func likeStatusDidChange(_ vc2: moreInfoViewController, to title: Bool) {
// set the text of the table cell here...
dataSource[updatedIndex].isLiked = !dataSource[updatedIndex].isLiked
let indexPath = IndexPath(row: updatedIndex, section: 0)
tableView.reloadRows(at: [indexPath], with: .automatic)
}
}
moreInfoViewController -
import UIKit
class moreInfoViewController: UIViewController {
@IBOutlet var backBtn: UIButton!
@IBOutlet var titleLabel: UILabel!
@IBOutlet var locationLabel: UILabel!
@IBOutlet var theImage: UIImageView!
@IBOutlet var mainlikeBtn: UIButton!
@IBOutlet var mainTypeLbl: UILabel!
var currentID:String = ""
var isLiked = Bool()
weak var delegate: VC2Delegate?
override func viewDidLoad() {
super.viewDidLoad()
overrideUserInterfaceStyle = .light
self.navigationController?.setNavigationBarHidden(true, animated: true)
styles()
// "isLiked" variable to display whether or user liked this event
if (isLiked == true) {
// is Liked
mainlikeBtn.setImage(UIImage(named: "liked"), for: UIControl.State.normal)
} else {
// Not Liked
mainlikeBtn.setImage(UIImage(named: "unLiked"), for: UIControl.State.normal)
}
}
// Heart/Like Button Action. User can like event in this VC with this button and it will tell the firstVC (ViewController) to update "Like Status" there also
@IBAction func likeBtnAction(_ sender: Any) {
if (isLiked == true) {
// is Liked
isLiked = false
mainlikeBtn.setImage(UIImage(named: "unLiked"), for: UIControl.State.normal)
} else {
isLiked = true
mainlikeBtn.setImage(UIImage(named: "liked"), for: UIControl.State.normal)
}
// When User interacts with like Button, this function gets called that tells the firstVC (ViewController) to update as well.
// likeStatusDidChange function is located at the bottom of the (ViewController) with extension ViewController.
delegate?.likeStatusDidChange(self, to: true)
}
// Go Back To FirstVC (ViewController)
@IBAction func previousVC(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
func styles() {
titleLabel.numberOfLines = 1
titleLabel.adjustsFontSizeToFitWidth = true
locationLabel.numberOfLines = 1
locationLabel.adjustsFontSizeToFitWidth = true
backBtn.transform = CGAffineTransform(rotationAngle: -CGFloat.pi / 2)
theImage.layer.borderColor = UIColor.black.cgColor
theImage.layer.borderWidth = 2
theImage.layer.cornerRadius = 10
}
}
解决方案
当您从 userdefaults 获取数组时,它会为您提供Any
类型数组,因此您需要将其转换为Int
数组并在使用前检查它是否为零。所以你可以使用这个代码块。
if let savedDataKey = UserDefaults.standard.array(forKey: "savedDataKey") as? [Int] {
print(savedDataKey)
}
推荐阅读
- powershell - PowerShell Compare-Object 可以进行二进制比较吗?
- asp.net - 如果我使用的是 Net Core 3.1,如何在互联网上发布我的 react 网页?
- react-table - 反应表工具栏AllRowsExpanded 不起作用
- ng-zorro-antd - NzDropdown 中的 NzTree 无法正确渲染
- video - 如何使用 FFmpeg 平铺视频
- pyspark - Pyspark 从零开始的关联分析
- r - 在 R 中更改 DF 中 2 列的格式
- python - 如何在python中更新mondodb中的许多记录?
- javascript - 使用 getIdToken 作为 Google Sheet API 的授权令牌
- reactjs - 如何从页面中删除数据并且它不显示?