ios - NSUserDefaults 不适用于 Swift 中的 UITableView

标签 ios swift uitableview nsuserdefaults

我对 Swift 比较陌生,正在制作一个基本的作业日记应用程序。到目前为止,我拥有的是嵌入在导航 Controller 中的 UITableView,该导航 Controller 嵌入在选项卡栏 Controller 中。我已经成功地实现了拉动刷新,在 UIAlertView 中添加数据并在刷新后用这些数据填充表。我需要这个应用程序的持久数据,我听说 NSUserDefaults 是实现此目的的最佳方法,但它对我不起作用。我可以看到它正在添加到 NSUserDefaults 中,但在我关闭并重新打开应用程序后,它似乎没有重新出现在 UITableView 中。有什么建议么?我的代码如下。另外,为了将这些数据放到网上,有没有办法使用 Google 表格作为我的应用程序的在线数据库?

import UIKit
var classesData = [String]()
var teachersData = [String]()
let defaults = NSUserDefaults.standardUserDefaults()
var tableData1 = defaults.valueForKey("classesData") as! NSArray
var tableData2 = defaults.valueForKey("teachersData") as! NSArray

class ClassesList: UIViewController, UITableViewDelegate, UITableViewDataSource, UIPopoverPresentationControllerDelegate {
lazy var refreshControl: UIRefreshControl = {
    let refreshControl = UIRefreshControl()
    refreshControl.addTarget(self, action: "handleRefresh:", forControlEvents: UIControlEvents.ValueChanged)

    return refreshControl
}()
@IBOutlet weak var tableView: UITableView!
@IBAction func addClass(sender: AnyObject) {
    var subjectTextField: UITextField?
    var teacherTextField: UITextField?
    let alertController = UIAlertController(title: "Add Class", message: "Please input the name of the subject and the teaceher", preferredStyle: .Alert)
    let done = UIAlertAction(title: "Done", style: .Default, handler: { (action) -> Void in
        classesData.append(subjectTextField!.text!)
        teachersData.append(teacherTextField!.text!)
        print(classesData)
        print(teachersData)
    })
    let cancel = UIAlertAction(title: "Cancel", style: .Cancel) { (action) -> Void in
    }
    alertController.addAction(done)
    alertController.addAction(cancel)
    alertController.addTextFieldWithConfigurationHandler { (textField) -> Void in
        // Enter the textfiled customization code here.
        subjectTextField = textField
        subjectTextField?.placeholder = "Subject"
    }
    alertController.addTextFieldWithConfigurationHandler { (textField) -> Void in
        // Enter the textfiled customization code here.
        teacherTextField = textField
        teacherTextField?.placeholder = "Teacher"
    }
    presentViewController(alertController, animated: true, completion: nil)

}

override func viewDidLoad() {
    super.viewDidLoad()
    self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "classCell")
    self.tableView.addSubview(self.refreshControl)


    // Do any additional setup after loading the view, typically from a nib.
}

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

}
func handleRefresh(refreshControl: UIRefreshControl) {
    defaults.setValue(classesData, forKey: "classesData")
    defaults.setValue(teachersData, forKey: "teachersData")
    print(tableData1)
    defaults.synchronize()
    self.tableView.reloadData()
    refreshControl.endRefreshing()
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return classesData.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("classCell")! as UITableViewCell

    cell.textLabel?.text = (tableData1[indexPath.row] as? String)! + " , " + (tableData2[indexPath.row] as? String)!

    return cell
}

}

最佳答案

启动时,您使用 tableData1 和 tableData2 来存储默认信息,但classesData 和 TeachersData 被初始化为空。当应用程序启动时,它会调用 numberOfRowsInSection 并返回零的classesData.count。您遇到的另一个问题是您的应用程序将在第一次运行时崩溃,因为您正在使用空的 NSUserDefaults 数据初始化它。重置 iOS 模拟器然后运行你的应用程序,它会崩溃。您需要检查并处理 NSUserDefaults 中的空数据,此处介绍:how to save and read array of array in NSUserdefaults in swift?

我建议如下: 1) 删除 tableData1 和 tableData1 并替换为应用程序中各处的classesData 和teacherData。 2) 创建一个名为 loadUserDefaults() 的新函数,该函数在 viewDidLoad 中调用,该函数从 NSUserDefaults 加载数据,同时检查空的 NSUserDefaults 数据。 3)在handleRefresh()中只需保存数据,重新加载 TableView 并结束刷新。根据这些建议,工作代码如下。

import UIKit
var classesData = [String]()
var teachersData = [String]()
let defaults = NSUserDefaults.standardUserDefaults()

class ClassesList: UIViewController, UITableViewDelegate, UITableViewDataSource, UIPopoverPresentationControllerDelegate {
    lazy var refreshControl: UIRefreshControl = {
        let refreshControl = UIRefreshControl()
        refreshControl.addTarget(self, action: "handleRefresh:", forControlEvents: UIControlEvents.ValueChanged)

        return refreshControl
    }()
    @IBOutlet weak var tableView: UITableView!
    @IBAction func addClass(sender: AnyObject) {
        var subjectTextField: UITextField?
        var teacherTextField: UITextField?
        let alertController = UIAlertController(title: "Add Class", message: "Please input the name of the subject and the teaceher", preferredStyle: .Alert)
        let done = UIAlertAction(title: "Done", style: .Default, handler: { (action) -> Void in
            classesData.append(subjectTextField!.text!)
            teachersData.append(teacherTextField!.text!)
        })
        let cancel = UIAlertAction(title: "Cancel", style: .Cancel) { (action) -> Void in
        }
        alertController.addAction(done)
        alertController.addAction(cancel)
        alertController.addTextFieldWithConfigurationHandler { (textField) -> Void in
            // Enter the textfiled customization code here.
            subjectTextField = textField
            subjectTextField?.placeholder = "Subject"
        }
        alertController.addTextFieldWithConfigurationHandler { (textField) -> Void in
            // Enter the textfiled customization code here.
            teacherTextField = textField
            teacherTextField?.placeholder = "Teacher"
        }
        presentViewController(alertController, animated: true, completion: nil)

    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "classCell")
        self.tableView.addSubview(self.refreshControl)
        loadUserDefaults()
    }

    func handleRefresh(refreshControl: UIRefreshControl) {
        defaults.setValue(classesData, forKey: "classesData")
        defaults.setValue(teachersData, forKey: "teachersData")
        defaults.synchronize()
        self.tableView.reloadData()
        refreshControl.endRefreshing()
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return classesData.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("classCell")! as UITableViewCell
        cell.textLabel?.text = (classesData[indexPath.row] as? String)! + " , " + (teachersData[indexPath.row] as? String)!

        return cell
    }

    func loadUserDefaults() {
        if let tempClassArray = defaults.valueForKey("classesData") {
            classesData = tempClassArray as! [String]
        }

        if let tempTeacherArray = defaults.valueForKey("classesData") {
            teachersData = tempTeacherArray as! [String]
        }
    }

}

关于ios - NSUserDefaults 不适用于 Swift 中的 UITableView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34113130/

相关文章:

iphone - 单击 TTStyledTextLabel 选择 UITableViewCell

ios - 初始化 super init 和其他

ios - 第一个屏幕后无法自定义导航栏。

ios - UILabel - 自动换行文本

ios - 使用 Xib 创建的自定义 View 在 Interface Builder 中不起作用

ios - 当一个 Label adjustFontSizeToFitWidth 时,在 UITableViewCell 的 UILabels 上设置匹配的字体大小

ios - 关闭 UITableView 单元格中 UITextfield 的键盘

ios - NSComparisonResult 选项

ios - 带指示器的圆形进度条

iphone - performSelector vs 直接调用性能