简体   繁体   中英

Saving, retrieving and displaying dynamic table data with Swift

Im trying to toggle a UISwitch on or off in Swift from results stored in Core Data.

I am loading the data from a json file, in this format:

[{
    fruit = Apple;
    id = 01;
}, {
    fruit = Banana;
    id = 02;
}, {
    fruit = Orange;
    id = 03;
}

...and it is populating dynamic table rows with the data. I have a repeating template with a UISwitch on the right side of the row.

Like this:

  • UISwitch "Apple" State: OFF
  • UISwitch "Banana" State: OFF
  • UISwitch "Orange" State: OFF

How do I go about targeting a specific switch to turn on or off with the returned items to toggle on?

I imagine I will need to store an array of id's that I added to the data set. For example

fruits = ["02","03"]

...and have the code find rows with that ID? I am a bit confused on how to go about doing this.

My end result would look like this when the view loaded:

  • UISwitch "Apple" State: ON
  • UISwitch "Banana" State: ON
  • UISwitch "Orange" State: OFF

...depending on what the user selected.

Any help would be greatly appreciated.

Let suppose your fruits array having these fruits -

[{
    fruit = Apple;
    id = 01;
}, {
    fruit = Banana;
    id = 02;
}, {
    fruit = Orange;
    id = 03;
}]

And selected fruits ID Array having these -

["02","03"]

So now populate the table row by adding these code snippet in your 'cellForRowAt' method -

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell:UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "Cell") as UITableViewCell!

    let fruitsDict = fruitsArray.object(at: indexPath.row) as! NSDictionary

    // I've used tag for getting fruit label and fruit switch view, you can use your own custom table view cell here for that.

    let lblFruitName = cell.contentView.viewWithTag(1) as! UILabel
    let fruitSwitch = cell.contentView.viewWithTag(2) as! UISwitch

    lblFruitName.text = fruitsDict.value(forKey: "fruit") as? String

    if(selectedFruitsIDArray.contains(fruitsDict.value(forKey: "id") as? String ?? "")){ // It contains fruit id

        fruitSwitch.setOn(true, animated: true)

    }
    else{

        fruitSwitch.setOn(false, animated: true)
    }

   return cell
}

Where fruitsArray is your all fruits array and selectedFruitsIDArray is selected fruits ID array.

I hope it will help you to start with.

if we are thinking about your data for a second, have you ever thought about adding some enable property of a boolean type inside each item in your Dictionary. So when a user taps on cell or the switch this cell then you could change this property value from false to true vice-versa.

user taps on switch 
change the enable property to true or vice versa
change switch from off to on or vice versa  
save into coreData

instead of using Dictionary, I would have a reference type data structure such as a class in which you can transform dictionary to obj vice-versa. (not required, but it makes your life easier, of course when you are saving or updating you transform that object to Dictionary)

    class Item {
    var id:Int
    var fruit:String
    var shouldBeEnabled:Bool

    init(id:Int, fruit:String, enable:Bool = false) {
      self.id  = id
      self.fruit = fruit
      shouldBeEnabled = enable
    }
    // from dict to item
    static func transform(dict:[String:Any]) -> Item {
        var id = dict["id"] as! Int // use optional instead of explicit unwrapping 
        var fruit = dict["fruit"] as! String
        var enabled = dict["enable"] as! Bool
        return Item(id: id, fruit: fruit, enable: enabled)
    }

    // from item to dict 
    static func transform(item:Item) -> [String:Any] {
        var dict = [String:Any]()
        dict["id"] = item.id
        dict["fruit"] = item.fruit
        dict["enable"] = item.shouldBeEnabled
        return dict
     }

 }

So next time the user comes into your app the state of the switch is saved into enabled, then you are populating your tableView then you should do a check

 consider you transform all your dict into object 
   if (data[indexPath.row].shouldBeEnabled == true) { // turn on switch }
   else { // turn off } 

Now your code has the ability: save user's change, and can load it anytime

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM