Search code examples
iosswiftxcodeuitableviewsections

UiTableView organize items by section programmatically


Im trying to group users based off of their location. For instance, anyone in NYC should be under the NYC section of the tableview and anyone in LA should be under that section.

//Sets up the sections
override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {

    //Sets the header view
    guard let header = view as? UITableViewHeaderFooterView
        else {
            return
    }

    //Sets the properties.
    view.tintColor = ChatMessageCell.indexedColor
    header.textLabel?.textColor = UIColor.white
    header.textLabel?.font = UIFont(name: "Open Sans Bold", size: 11)
    header.backgroundColor = ChatMessageCell.indexedColor
    header.textLabel?.textAlignment = .center

    //Sets the variable headerText = to the text labels header
    self.headerText = header.textLabel?.text!

}

I created a variable called headerText that stores the header's text label. In numberOfRowsInSection, I compare the user's location with the header title. If they match, I return the user but if they do not, nothing should be returned

//Sets the number of rows equal to the amount of Users.
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    //Observes the users (Firebase
    refHandle = ref.child("Users").observe(.childAdded, with: { (snapshot) in

        if let dictionary = snapshot.value as? [String : AnyObject]{
            let user = Users()
            user.id = snapshot.key
            user.setValuesForKeys(dictionary)


            //If statement to see if their location is equal to header it should be under
            //This array is empty + meant to store only the users whose location is equal to the section title
            if user.location == self.headerText{
                return user
            }
            else{
                return 0
            }

        }
    })

}

Solution

  • I think your code has two issues:

    • To create / modify header views, you should implement viewForHeaderInSection (instead of doing it in willDisplayHeaderView)
    • You should not store state data (like the headerText) of the somehow current header. This highly depends on Framework implementation details of the order in which the table displays headers and cells.

    So you need differend methods to access your grouping/header criteria and to access the cell data.

    A trivial example:

    • First, you would calulate the sections / locations (somewhere in viewDidLoad or viewDidAppear), sort them alphabetically and store them in an array named e.g. locations or somehow.
    • In numberOfRowsInSection you return the number of locations (e.g. locations.count
    • In viewForHeaderInSection you would retrieve the data beloning to the provided section, e.g. return locations[section]
    • In numberOfRowsInSection you would count the number of users beloning to the given section
    • In cellForRow you would calculate then return a cell that contains the user data.