我有一张表格,其工作方式如下。如果选择了某一行,则会将与所选行相应的金额添加到
var total
中,并添加一个复选标记。如果取消选择,则将减去该金额,并将复选标记设置为无。
在尝试将数据保存/检索到NSUserDefaults之前,我的代码正常运行。
错误是:当我选择第一行时,它会减去金额而不是添加;选择行后,如果我点击返回按钮然后再回到同一屏幕,则不显示复选标记。
在这个结构中,当我尝试从NSUserDefaults检索indexPathForCellSelected
时,即使在进行分配之前检查了if indexPathForCellSelected != nil
,它也会计算为nil。
致命错误:在展开可选值时意外地找到了nilif indexPathForCellSelected != nil { self.tableView.cellForRowAtIndexPath(indexPathForCellSelected!)?.
accessoryType = .Checkmark
}
class NinethViewController: UIViewController, UITableViewDelegate,UITableViewDataSource {
var total = 0
var indexRowRetrieved:Int?
var rowSelected:Int?
var indexRowSelectedKey = "indexRowKey"
var amountKey = "amountKey"
var totalKey = "totalKey"
let indexPathKey = "indexPathForCellSelected"
var indexPathForCellSelected: NSIndexPath?
struct Item {
var name:String // name of the row
var selected:Bool // whether is selected or not
var amount: Int // value of the item
}
var extras = [
Item(name:"Inside Cabinets",selected: false, amount: 5),
Item(name:"Inside Fridge",selected: false, amount: 5),
Item(name:"Inside Oven",selected: false, amount: 5),
Item(name:"Laundry wash & dry",selected: false, amount: 10),
Item(name:"Interior Windows", selected: false, amount: 5)
]
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
// loadData from NSUserDefaults
loadData()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return extras.count
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
// configure the cell
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)
-> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell")
cell?.textLabel?.text = extras[indexPath.row].name
return cell!
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// if the cell has not been selected before
if !extras[indexPath.row].selected {
// marks the cell as selected
extras[indexPath.row].selected = true
tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .Checkmark
self.total += extras[indexPath.row].amount
indexPathForCellSelected = indexPath
rowSelected = indexPath.row
print(total)
// save all info in NSUserDefaults
saveData()
} else {
// marks the cell as not selected
extras[indexPath.row].selected = false
tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .None
self.total -= extras[indexPath.row].amount
print(total)
}
}
func saveData(){
// save indexPathForCellSelected in NSUserDefaults
if indexPathForCellSelected != nil {
let data = NSKeyedArchiver.archivedDataWithRootObject(indexPathForCellSelected!)
NSUserDefaults.standardUserDefaults().setObject(data, forKey: indexPathKey)
// save indexRowSelected
NSUserDefaults.standardUserDefaults().setInteger(rowSelected!, forKey: indexRowSelectedKey)
// save amount for corresponding row in NSUserDefaults
NSUserDefaults.standardUserDefaults().setObject(extras[rowSelected!].amount, forKey: amountKey)
//save total in NSUserDefaults
NSUserDefaults.standardUserDefaults().setObject(total, forKey: totalKey)
}
}
func loadData() {
//retrieve indexPathForCellSelected from NSUserDefaults
if let retrievedIndexPath = NSUserDefaults.standardUserDefaults().dataForKey(indexPathKey) {
if let data1 = NSKeyedUnarchiver.unarchiveObjectWithData(retrievedIndexPath) as? NSIndexPath{
indexPathForCellSelected = data1
}
}
// retrieve the index for row selected to select the state of the row: true or false
if let retrievedIndexRow = NSUserDefaults.standardUserDefaults().integerForKey(indexRowSelectedKey) as? Int {
indexRowRetrieved = retrievedIndexRow
extras[retrievedIndexRow].selected = true
}
// retrieve amount for corresponding row in NSUserDefaults
if let itemAmount = NSUserDefaults.standardUserDefaults().objectForKey(amountKey) as? Int {
extras[indexRowRetrieved!].amount = itemAmount
// assign checkmark to row selected
if indexPathForCellSelected != nil {
self.tableView.cellForRowAtIndexPath(indexPathForCellSelected!)?.accessoryType = .Checkmark
}
}
// retrieve total from NSUserDefaults
if let totalRetrieved = NSUserDefaults.standardUserDefaults().objectForKey(totalKey) as? Int {
total = totalRetrieved
print(total)
}
}
}