我对 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/