Grumme
Grumme

Reputation: 806

Dynamic tableview with sections

I'm trying to create a dynamic tableview. Right now i got an array of unsorted exercise objects (Some of them are the same, but with different logged information).

I need first of all, to create a section for each unique exercise which is added to the log.

After that i need to add all the exercises to the specific sections, so the logged exercises for 'Bench Press' goes under the 'Bench Press' section etc.

Right now it says - TmpExercise has no subscript members, when i try to assign the label.

Is there a better way to do this?

I have been working on different solutions for several hours now, so i hope some of you can help me :-).

struct Objects {

    var sectionName : String!
    var sectionObjects : [TmpExercise]!
}

var objectArray = [Objects]()
var tmpArray = [TmpExercise()]
var exerciseDictionary = Dictionary<String, TmpExercise>()


override func viewDidLoad() {
    super.viewDidLoad()


    for exercise in log!.tmpExercises {
        exerciseDictionary[(exercise.tmpExercise!.name)] = exercise
    }

    for (key, value) in exerciseDictionary {

        tmpArray = [TmpExercise()]

        for exercise in log!.tmpExercises {
            if exercise.tmpExercise!.name == key {
                tmpArray.append(exercise)
            }
        }

        objectArray.append(Objects(sectionName: key, sectionObjects: tmpArray))
        tmpArray.removeAll()
    }
}

override func viewDidAppear(animated: Bool) {
    tableView.reloadData()
}

// MARK: - Table view data source

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return objectArray.count
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return objectArray[section].sectionObjects.count-1
}

func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return objectArray[section].sectionName
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Log Detail", forIndexPath: indexPath)// as! UITableViewCell

    cell.textLabel!.text = objectArray[indexPath.section].sectionObjects[indexPath.row]
    //  TmpExercise has no subscript members

    return cell
}

EDIT: I have tried to implement @Mohamed Mostafa answer, please take a look at the following code for whole my class.

I have uploaded an image of the content right now. Deadlift is fine with two cells, but Squat has 5 cells and should only contain 3 cells. The two first cells under Squat is named deadlift, but the rest is correct.

Can someone please tell me what i'm doing wrong?

enter image description here

struct Objects {

var sectionName : String!
var sectionObjects : [TempExercise]!
}

 struct TempExercise {

var Name : String!
}

class SelectedLogViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

@IBOutlet weak var tableView: UITableView!

var log: Log?
var objectArray = [Objects]()
var tmpObjectArray = [Objects]()

var tmpArray = [TempExercise()]

var test: Objects?

var exerciseDictionary = Dictionary<String, String>()

override func viewDidLoad() {
    super.viewDidLoad()

    for exercise in log!.tmpExercises {
        exerciseDictionary[(exercise.tmpExercise!.name)] = exercise.tmpExercise!.name
    }


    for (key, value) in exerciseDictionary {
        tmpArray = [TempExercise(Name:value)]

        objectArray.append(Objects(sectionName: key, sectionObjects: tmpArray))

        tmpArray.removeAll()
    }

    for uniqueExercise in objectArray {
        for logExercise in log!.tmpExercises {
            if uniqueExercise.sectionName == logExercise.tmpExercise!.name {

                let tmpEx = TempExercise(Name: logExercise.tmpExercise!.name)
                tmpArray.append(tmpEx)

            }
            test = Objects(sectionName: uniqueExercise.sectionName, sectionObjects: tmpArray)
        }
        tmpObjectArray.append(test!)
        test?.sectionObjects.removeAll()
    }
}


// MARK: - Table view data source

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return objectArray.count
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return tmpObjectArray[section].sectionObjects.count
}

func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return objectArray[section].sectionName
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Log Detail", forIndexPath: indexPath)// as! UITableViewCell

    cell.textLabel!.text = tmpObjectArray[indexPath.section].sectionObjects[indexPath.row].Name

    return cell
}
}

Upvotes: 1

Views: 122

Answers (1)

Mohamed Mostafa
Mohamed Mostafa

Reputation: 1057

The problem happens because you try to set label.text with an object while it needs a string value, so it caused an error.

i tried to make a working solution near what you want to do.

struct Objects {

    var sectionName : String!
    var sectionObjects : [TempExercise]!
}

struct TempExercise {

    var Name : String!
}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        for (key, value) in exerciseDictionary {

            tmpArray = [TempExercise(Name:value)]

            objectArray.append(Objects(sectionName: key, sectionObjects: tmpArray))
            tmpArray.removeAll()
        }
    }


// Solution for duplication    
          for uniqueExercise in objectArray {
            tmpArray.removeAll()   // YOU MISSED TO EMPTY tmpArray Which caused previous data to propagate with you to next iteration
            for logExercise in log.loggedExercises {
                if uniqueExercise.sectionName == logExercise.name {

                    let tmpEx = TempExercise(Name: logExercise.name)
                    tmpArray.append(tmpEx)

                }
                test = Objects(sectionName: uniqueExercise.sectionName, sectionObjects: tmpArray)
            }
            tmpObjectArray.append(test!)
            test?.sectionObjects.removeAll()
        }


    // MARK: - Table view data source

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return objectArray.count
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return objectArray[section].sectionObjects.count-1
    }

    func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return objectArray[section].sectionName
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Log Detail", forIndexPath: indexPath)// as! UITableViewCell

        cell.textLabel!.text = objectArray[indexPath.section].sectionObjects[indexPath.row].Name
        //  TmpExercise has no subscript members

        return cell
    }


}

Upvotes: 1

Related Questions