Swift 4,使用 Array 和 TableViewCell 存储和显示数据

Posted

技术标签:

【中文标题】Swift 4,使用 Array 和 TableViewCell 存储和显示数据【英文标题】:Swift 4, Storing and Displaying Data Using Array and TableViewCell 【发布时间】:2018-05-09 21:42:22 【问题描述】:

我正在制作一个允许用户保持用户名和密码顺序的应用程序。目前,当用户退出应用程序时,我遇到了问题,数据或 TableViewCell 未存储或显示。我正在使用一个数组。

我假设是因为之后没有存储数据。 CoreData 或 UserDefaults 是一个简单的解决方案吗?我想避免使用 Firebase。

有人可以解释或展示如何在代码中实现 CoreData/UserDefaults 吗? 我进行了很多搜索,但我发现很难理解如何在我的代码中应用它,尤其是数组和 TableViewCell。非常感谢您的帮助。

图片如下。

这是我的代码:

主视图控制器:

class MainViewController: UIViewController, UITableViewDataSource, UITableViewDelegate 
@IBOutlet weak var tableView:UITableView?


override func viewDidLoad() 
    super.viewDidLoad()


    // Do any additional setup after loading the view.


override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return informasjoner.count


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "InformasjonTableViewCell") as! InformasjonTableViewCell

    let informasjon:Informasjon = informasjoner[indexPath.row];

    if(informasjon.image != nil)
        cell.imageViewInfo?.image = informasjon.image
     else 
        cell.imageViewInfo?.image = UIImage(named: informasjon.imageName!)
    

    cell.epostLabel?.text = informasjon.labelEpost
    cell.passordLabel?.text = informasjon.labelPassord
    cell.applikasjonLabel?.text = informasjon.labelApplikasjon

    return cell


// EDIT / UPDATE CELL

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? 
    let informasjon = informasjoner[indexPath.row]

    let deleteAction = UITableViewRowAction(style: .default, title: "Delete")
        (action, indexPath) in
        self.deleteAction(informasjon: informasjon, indexPath: indexPath)
    
        //call delete action
    deleteAction.backgroundColor = .red;
    return [deleteAction]
    
private func deleteAction(informasjon: Informasjon, indexPath: IndexPath)
let alert = UIAlertController(title: "Delete",
                              message: "Are u sure?",
                              preferredStyle: .alert)

    let deleteAction = UIAlertAction(title: "Yes",
                                     style: .default) (action) in
        informasjoner.remove(at: indexPath.row)
        self.tableView?.deleteRows(at: [indexPath], with: .automatic)

    
    let cancelAction = UIAlertAction(title: "No",
                                     style: .default,
                                     handler: nil);
    alert.addAction(deleteAction);
    alert.addAction(cancelAction);
    present(alert, animated: true);



InformasjonTableViewCell:

 import UIKit

 class InformasjonTableViewCell: UITableViewCell 


@IBOutlet weak var imageViewInfo: UIImageView?
@IBOutlet weak var epostLabel: UILabel?
@IBOutlet weak var passordLabel: UILabel?
@IBOutlet weak var applikasjonLabel: UILabel!




override func awakeFromNib() 
    super.awakeFromNib()
    // Initialization code


override func setSelected(_ selected: Bool, animated: Bool) 
    super.setSelected(selected, animated: animated)





AddInfoVC:

import UIKit

class AddInfoVC: UIViewController, UITextFieldDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate 

@IBOutlet weak var txtEpost:UITextField?
@IBOutlet weak var ImageInfo:UIImageView?
@IBOutlet weak var txtPassord:UITextField?
@IBOutlet weak var txtApplikasjon: UITextField!


var newInfo = Informasjon()

@IBAction func btnSave(sender:UIButton)
print("Press Save!")
    if(newInfo.image == nil || newInfo.labelEpost?.count == 0 || newInfo.labelPassord?.count == 0 || newInfo.labelApplikasjon?.count == 0)
        let alertController = UIAlertController(title: "Alert", message: "Please set", preferredStyle: .alert)
        let okAction = UIAlertAction(title: "OK", style: .default)
            (action) in
        
        alertController.addAction(okAction)
        self.present(alertController, animated: true, completion: nil);

     else
        informasjoner.append(newInfo);
        navigationController?.popViewController(animated: true)
        let mainViewController = self.navigationController?.topViewController as? MainViewController
        mainViewController?.tableView?.reloadData()
    


override func viewDidLoad() 
    super.viewDidLoad()
    //Tap to ImageView
    let tapGestureToImageView = UITapGestureRecognizer(target: self, action: #selector(tapToImageView(sender:)))
    tapGestureToImageView.numberOfTapsRequired = 1
    ImageInfo?.isUserInteractionEnabled = true;
    ImageInfo?.addGestureRecognizer(tapGestureToImageView);

    self.txtEpost?.delegate = self;
    self.txtPassord?.delegate = self;
    self.txtApplikasjon?.delegate = self;



型号

Informasjon.swift:

import Foundation
import UIKit

class Informasjon 
var imageName: String?
var image: UIImage?
var labelEpost: String?
var labelPassord: String?
var labelApplikasjon: String?
convenience init(imageName:String, labelEpost:String, labelPassord:String,labelApplikasjon:String ) 
    self.init()
    self.imageName = imageName
    self.labelEpost = labelEpost
    self.labelPassord = labelPassord
    self.labelApplikasjon = labelApplikasjon


Picture 1 -> How the Application looks from the Storyboard.

Picture 2 -> How the Application looks from Simulator.

【问题讨论】:

猜猜,基本上你的问题是关于 UITableView CoreData/UserDefaults Swift4 示例。 我真的,真的希望你打算完全加密密码。 有什么例子吗? @亚历山大 好吧,今晚我会努力弥补你的,好吗? 那么,这个教程medium.com/@riccione83/easy-use-of-realm-in-swift-444f41a5742d 怎么样?它使用单例,这不是最安全的选择,但可能适合一开始。 【参考方案1】:

UserDefaults 通常是最容易使用的数据库。如果您只有一个 array 可以存储/检索,请坚持使用它。如果您有更多信息,请使用 CoreData/Realm 等更大的信息。

let array = []()
let defaults = UserDefaults.standard
defaults.set(array, forKey: "SavedStringArray")

请随时查看以下答案和教程。

how to save and read array of array in NSUserdefaults in swift? https://medium.com/@nimjea/userdefaults-in-swift-4-d1a278a0ec79

如果仍然难以理解,我建议查看 UserDefaults - NSUserDefaultsObjective-C 版本。即使您不熟悉 Objective-C 语法,它也可能更容易理解。

Save string to the NSUserDefaults?

现在的问题是在使用 UITableView 时在哪里使用这些方法。

当您想要更改或检索存储中的数据时(在我们的例子中为 UserDefaults)。

对于实例,您可以在 tableView(:didSelectRowAt:) 中调用 tableView(:cellForRowAt:) 方法更改存储的数组,或者您可以在 tableView(_:cellForRowAt:) 中检索数据

使用Realm查看官方网站 https://realm.io/docs/swift/latest

【讨论】:

不要使用 UserDefaults 来存储应用数据。将数据写入文件。 @rmaddy 例子? @Alexander 我会试试的。但是我到底在哪里实现它呢?对不起我的愚蠢,我对 Swift 很陌生,尤其是 UserDefaults。 现在有点忙,如果没有其他人能够做到,稍后会尝试为您提供更完整的答案。 @Alexander 好的,我还没有弄清楚.. idk 我做错了什么。我会等:)【参考方案2】:

您应该只使用 NSUserDefaults 来存储首选项 - 只是您的应用功能的首选项,没有其他内容。像用户数据这样的其他任何东西都应该存储在其他地方。特别是如果说这是敏感的,并且您不想冒用户数据的风险,因为 plist 文件直接在应用程序目录中可用。

使用 UserDefaults 存储应用数据的另一个缺点是所有数据都将存储为属性列表文件。整个文件是作为一个整体读入和写出的,所以如果你使用 UserDefaults 来存储大量只改变部分的数据,你将浪费大量时间进行不必要的 I/O。

相反,CoreData/Realm 始终是持久化应用数据的更好选择。

学习如何在 CoreData 中存储 -

https://www.raywenderlich.com/173972/getting-started-with-core-data-tutorial-2 https://in.udacity.com/course/ios-persistence-and-core-data--ud325 https://medium.com/xcblog/core-data-with-swift-4-for-beginners-1fc067cca707 https://code.tutsplus.com/tutorials/core-data-and-swift-managed-objects-and-fetch-requests--cms-25068

学习如何在 Realm 中存储 -

https://realm.io/docs/tutorials/realmtasks/ https://www.appcoda.com/realm-database-swift/ https://www.raywenderlich.com/112544/realm-tutorial-getting-started

【讨论】:

以上是关于Swift 4,使用 Array 和 TableViewCell 存储和显示数据的主要内容,如果未能解决你的问题,请参考以下文章

滑块的 Swift 2 错误

过滤两个数组Swift

Swift4.2~数组和字典(Array, Dictionary)基本类型转换

Swift 4 JSON Parsing(预期解码 Array<Any> 但找到了字典)

Swift初见Swift数组

Swift 5.X——Array