NSUserDefaults和UITableView中的持久性

时间:2016-12-01 19:28:26

标签: ios arrays swift uitableview nsuserdefaults

我有一个快速的编码问题。首先,我使用XCode 8和swift 2.这是我的viewcontroller的快速图像,以便您可以获得更好的主意。 Image of my viewcontroller

在上图中,您插入一个目标(文本字段中的文本)并按提交。提交按钮(“提交目标”)将文本字段中的文本插入到数组中。然后,此数组将显示在tableview中。

我的问题是,如何将NSUserDefualts实现到此viewcontroller中以保存数组?如果用户从tableview中删除其中一个目标,则还需要能够更新阵列。

以下是我的viewcontroller代码:

//
//  VCWeeklyGoals.swift
//  FitNote
//
//  Created by ---- on 9/21/16.
//  Copyright © 2016 Haiden Stiles. All rights reserved.
//

import UIKit

class VCWeeklyGoals: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {

    //MARK: Properties








//DATE AND TIME
@IBOutlet weak var labelDate: UILabel!
var timer = NSTimer()

@objc func tick() {
    labelDate.text = NSDateFormatter.localizedStringFromDate(NSDate(), dateStyle: .MediumStyle, timeStyle: .MediumStyle)
}
//END DATE AND TIME

//BEGINNING ROUNDED BUTTONS FOR MONDAY THROUGH FRIDAY
//@IBOutlet weak var roundedButtonMonday: UIButton!


    //ROUNDED BUTTON FOR SUBMIT GOAL
@IBOutlet weak var roundedButtonSubmitGoal: UIButton!
    //END ROUNDED BUTTON FOR SUBMIT GOAL

//END ROUNDED BUTTONS FOR MONDAY THROUGH FRIDAY







//BEGINNING OF TABLE FUNCTIONS AND PROPERTIES

@IBOutlet var tableView: UITableView!
@IBOutlet var insertedGoal: UITextField!

//var tableTitles = NSUserDefaults.standardUserDefaults().arrayForKey("tableTitles") as! [String]
var tableTitles = [String]()




@IBAction func buttonSubmitGoal(sender: UIButton) {

    self.view.endEditing(true)

    var error = ""

    if insertedGoal.text == "" {

        error = "Please enter a goal!"
    } else {

        tableTitles.append(insertedGoal.text!)
        self.tableView.reloadData()
    }

    if error != "" {

        let alert = UIAlertController(title:"Error In Form", message: error, preferredStyle: UIAlertControllerStyle.Alert)
        alert.addAction(UIAlertAction(title:"OK", style: .Default, handler: { action in

            //self.dismissViewControllerAnimated(true, completion:nil)

        }))

        self.presentViewController(alert, animated:true, completion:nil)

    }

    insertedGoal.text = ""

}



//func numberOfSectionsInTableView(tableView: UITableView) -> Int {
//    return 1
//}


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

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

    let cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell

    let object = tableTitles[indexPath.row] 
    cell.textLabel!.text = object

    return cell
}

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == UITableViewCellEditingStyle.Delete {
        tableTitles.removeAtIndex(indexPath.row)
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
    }
}

//END OF TABLE FUNCTIONS AND PROPERTIES



//OVERRIDE FUNCTIONS

override func viewDidLoad() {
    super.viewDidLoad()



    if let temp = NSUserDefaults.standardUserDefaults().objectForKey("tableTitles") as? [String] {
        tableTitles = temp
    }


    // Do any additional setup after loading the view.

    //TABLE PROPERTIES
    self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")

    self.insertedGoal.delegate = self
    tableView.delegate = self
    tableView.dataSource = self
    //END TABLE PROPERTIES

    //DATE PROPERTIES
    timer = NSTimer.scheduledTimerWithTimeInterval(1.0,
        target: self,
        selector: #selector(tick),
        userInfo: nil,
        repeats: true)
    //END DATE PROPERTIES

    //ROUNDED BUTTON FOR MONDAY THROUGH FRIDAY PROPERTIES
    //MONDAY
    //roundedButtonMonday.backgroundColor = UIColor.whiteColor()
    //roundedButtonMonday.layer.cornerRadius = 6
    //roundedButtonMonday.layer.borderWidth = 0.5
    //roundedButtonMonday.layer.borderColor = UIColor.blueColor().CGColor


        //ROUNDED BUTTON FOR SUBMIT GOAL
    roundedButtonSubmitGoal.backgroundColor = UIColor.clearColor()
    roundedButtonSubmitGoal.layer.cornerRadius = 7
    roundedButtonSubmitGoal.layer.borderWidth = 1
    roundedButtonSubmitGoal.layer.borderColor = UIColor.blueColor().CGColor

        //END ROUNDED BUTTON FOR SUBMIT GOAL
    //END ROUNDED BUTTON FOR MONDAY THROUGH FRIDAY PROPERTIES

    //DATE PICKER

    //END DATE PICKER
}

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

}

1 个答案:

答案 0 :(得分:0)

我一直在研究你的问题,这是我的解决方案

首先我创建一个目标模型,是一个简单的模型,这只有目标的文本,还有两个静态方法,一个用于保存,另一个用于加载

class Goal: NSObject {

var text : String = ""

init(text: String) {
    super.init()
    self.text = text
}

static func loadFromFile(fileName:String) ->[Goal]?
{
    let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true);
    let docsDirectory = paths[0];
    let path = docsDirectory + "/" + fileName;
    let data = NSArray(contentsOfFile: path);

    if(data != nil)
    {
        var returnArray : [Goal] = []
        for object in data! {
            returnArray.append(Goal(text: object as! String))
        }
        return returnArray
    }

    return nil
}

static func saveToPlist(filename:String,goals:[Goal]) -> Bool {

    let toSaveArray = NSMutableArray();
    for goal in goals {
        toSaveArray.add(goal.text)
    }

    let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true);
    let docsDirectory = paths[0];
    let path = docsDirectory + "/" + filename;
    return toSaveArray.write(toFile: path, atomically: true);
}

}

这是我在ViewController上的实现,GoalTableViewCell是一个只有一个UILabel

的简单单元格
import UIKit

class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {

@IBOutlet weak var tfGoalTextAdd: UITextField!
@IBOutlet weak var btnAdd: UIButton!
@IBOutlet weak var tableView: UITableView!
var goals : [Goal] = []
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    self.tableView.estimatedRowHeight = 40;
    self.loadGoals()
    self.btnAdd.addTarget(self, action: #selector(addGoalWithTextFieldText), for: .touchUpInside)
}

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

public func loadGoals()
{
    if let arrayGoals = Goal.loadFromFile(fileName: "goals")
    {
        self.goals = arrayGoals
    }
}

public func addGoalWithTextFieldText()
{
    if(self.tfGoalTextAdd.text != nil && self.tfGoalTextAdd.text != "")
    {
        self.addGoal(text: self.tfGoalTextAdd.text!)
        self.tfGoalTextAdd.text = ""
    }
}

public func addGoal(text: String)
{
    self.goals.append(Goal(text: text))
    self.tableView.reloadData()
    if(Goal.saveToPlist(filename: "goals", goals: goals))
    {
        debugPrint("Successful saved")
    }
}

public func removeGoal(goal:Goal)
{
    goals.remove(at:goals.index(of: goal)!)
    self.tableView.reloadData()
    if(Goal.saveToPlist(filename: "goals", goals: goals))
    {
        debugPrint("Successful saved")
    }
}


public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
    return self.goals.count
}


public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
    let cell = tableView.dequeueReusableCell(withIdentifier: "GoalCell") as! GoalTableViewCell
    cell.setupWithGoal(goal: self.goals[indexPath.row])
    return cell
}


public func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    return true
}


public func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
    return .delete
}

public func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        // Delete the row from the data source

        //tableView.beginUpdates()
        self.removeGoal(goal: self.goals[indexPath.row])

        //tableView.endUpdates()

    } else if editingStyle == .insert {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }
}


}

我希望这有助于你