简体   繁体   中英

How do I get my array of dictionaries to populate my tableview?

I think I'm close, but I just need a little direction to help to finish. I want to populate a tableview with my data, but I'm stumped.

I have two arrays of dictionaries that hold user data: daily jobs, and weekly jobs.

Array #1:

let finalDailyJobsArray = [JobsAndHabits(name: "counters", multiplier: 1.0, assigned: "Sophie", order: 0),
                       JobsAndHabits(name: "bedroom", multiplier: 1.0, assigned: "Sophie", order: 1),
                       JobsAndHabits(name: "bathrooms", multiplier: 1.0, assigned: "Allan", order: 2),
                       JobsAndHabits(name: "laundry", multiplier: 1.0, assigned: "Mother", order: 3),
                       JobsAndHabits(name: "living room", multiplier: 1.0, assigned: "Father", order: 4),
                       JobsAndHabits(name: "dining room", multiplier: 1.0, assigned: "Father", order: 5),
                       JobsAndHabits(name: "dishes", multiplier: 1.0, assigned: "Allan", order: 6)]

And array #2:

let finalWeeklyJobsArray = [JobsAndHabits(name: "wash windows", multiplier: 1.0, assigned: "Father", order: 1),
                        JobsAndHabits(name: "weed garden", multiplier: 1.0, assigned: "Father", order: 0),
                        JobsAndHabits(name: "sweep porch", multiplier: 1.0, assigned: "Father", order: 2),
                        JobsAndHabits(name: "clean pool", multiplier: 1.0, assigned: "Mother", order: 4),
                        JobsAndHabits(name: "dusting & cobwebs", multiplier: 1.0, assigned: "Sophie", order: 3)]

In addition, I have two variables that also hold single bits of info.

Single variables:

let inspectionParent = "Mother"     // this is a daily job
let paydayParent = "Father"         // this is a weekly job

I want to put these into a tableview with a section for each user. It will look like this:

用户工作清单

As you can see, I figured out how to get the user images and user names out of my arrays, as well as how to determine the number of sections to create, but I can't for the life of me figure out how to customize the cellForRowAt property.

I want to list each individual's daily jobs and weekly jobs beneath their name. I'm guessing the trick lies in figuring out how to iterate over the arrays using the indexPath.row functionality, but so far my efforts haven't worked. Can someone please step in and help me?

What I've tried:

Attempt #1: I think this is the right direction, but I'm not sure how to get the cells to coordinate, or even where to put this code.

let userNames2 = finalUsersArray.map({ return $0.firstName }).sorted()
let jobAssignments2 = finalWeeklyJobsArray.map({ return $0.assigned }).sorted()
let userNames3 = finalUsersArray.filter({ return $0.firstName == "Father" })

Attempt #2: This repeated the same data in each section, which isn't what I want.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "customCell") as! JobSummaryCellB
    if User.finalUsersArray[indexPath.row].firstName == JobsAndHabits.finalWeeklyJobsArray[indexPath.row].assigned {
        cell.userNameLabel.text = JobsAndHabits.finalWeeklyJobsArray[indexPath.row].name
    }
    return cell

Attempt #3: Totally didn't work.

cell.userNameLabel.text = User.finalUsersArray.filter({ return $0.firstName == "Father" })

Attempt #4: Also didn't work (returned error)

if JobsAndHabits.finalWeeklyJobsArray[indexPath.row].assigned == User.finalUsersArray[indexPath] {
        cell.userNameLabel.text = JobsAndHabits.finalWeeklyJobsArray[indexPath.row].name

I found these articles, but couldn't figure out how to adapt them to my situation: article1 , article2 , article3

Any help would be awesome!!

Edit #1:

Here is my numberOfSections method:

func numberOfSections(in tableView: UITableView) -> Int {
    return User.finalUsersArray.count
}

And my viewForHeaderInSection method:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let cell = tableView.dequeueReusableCell(withIdentifier: "headerCell") as! JobSummaryCell
    cell.headerImage.image = User.finalUsersArray[section].photo
    cell.headerLabel.text = User.finalUsersArray[section].firstName
    return cell
}

And my two Structs:

struct User {
    var photo: UIImage
    var firstName: String
    var birthday: Int
    var passcode: Int
    var gender: String
    var childParent: String
}

struct JobsAndHabits {
    var name: String
    var multiplier: Double
    var assigned: String
    var order: Int

    static var finalDailyJobsArray = [JobsAndHabits]()
    static var finalWeeklyJobsArray = [JobsAndHabits]()

    static var inspectionParent = ""
    static var paydayParent = ""
}

Update #2: How finalUsersArray is populated.

static func loadMembers() {
    let firebaseUser = FIRAuth.auth()?.currentUser
    let ref = FIRDatabase.database().reference().child("users").child(firebaseUser!.uid)
    ref.child("members").observeSingleEvent(of: .value, with: { (snapshot) in
        for item in snapshot.children {
            if let snap = item as? FIRDataSnapshot {
                if let value = snap.value as? [String : Any] {
                    let birthday = value["birthday"] as! Int
                    let childParent = value["childParent"] as! String
                    let firstName = value["firstName"] as! String
                    let gender = value["gender"] as! String
                    let passcode = value["passcode"] as! Int
                    let profileImageUrl = value["profileImageUrl"] as! String
                    // get images
                    let storageRef = FIRStorage.storage().reference(forURL: profileImageUrl)
                    storageRef.data(withMaxSize: 1 * 1024 * 1024, completion: { (data, error) in
                        let pic = UIImage(data: data!)
                        let user = User(photo: pic!,
                                        firstName: firstName,
                                        birthday: birthday,
                                        passcode: passcode,
                                        gender: gender,
                                        childParent: childParent)
                        finalUsersArray.append(user)
                    })
                }
            }
        }
    })
}

You have to use like this :

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    let dailyJobAssignments = JobsAndHabits.finalDailyJobsArray.filter({ return $0.assigned == User.finalUsersArray[section].firstName }).count 
    let weeklyJobAssignments = JobsAndHabits.finalWeeklyJobsArray.filter({ return $0.assigned == User.finalWeeklyJobsArray[section].firstName }).count 
    return dailyJobAssignments+weeklyJobAssignments
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "customCell") as! JobSummaryCellB
    let dailyJobAssignments = JobsAndHabits.finalDailyJobsArray.filter({ return $0.assigned == User.finalUsersArray[indexPath.section].firstName })
    let weeklyJobAssignments = JobsAndHabits.finalWeeklyJobsArray.filter({ return $0.assigned == User.finalWeeklyJobsArray[indexPath.section].firstName })
    let jobAssignments = dailyJobAssignments + weeklyJobAssignments
    cell.userNameLabel.text = jobAssignments[indexPath.row].name
    return cell
}

So If I understand your problem you just want to customize how your cells is going to be displayed in your TableView. First of all, you have to indicate 2 informations to your TableView :

  • How many sections do you want to have ? In your case it will be equal to how many individual's o you have.

func numberOfSections(in: UITableView) Asks the data source to return the number of sections in the table view.

  • How many rows do you need for each section ? In your case it will be equal to how many jobs an individual have. (Daily + weekly jobs)

func tableView(UITableView, numberOfRowsInSection: Int) Tells the data source to return the number of rows in a given section of a table view. Required.

Then to customize your cells you need to :

  • Create a class for your custom cell. You use this identifier "customCell" but did you have a class to represent the design of your cell ?
  • Link your custom cell class to prototype cells of your table view within your storyboard
  • Connect outlets and actions from your custom cell to your custom cell class
  • Finally in the func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell just configure your cell using your outlets...

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