Search code examples
iosswiftdictionarynsdictionary

dictionary for tableView datasource


I am trying to use a dictionary for a tableView datasource, I am getting an object back from the database that contains a key and an array of values, so a [String: [String]]

    var requestedList = [String]()
    var keyArr = [String]()
    var requestedDictionary = [String: [String]]()

    let tQuery = PFQuery(className: "MyClass")
        tQuery.whereKey("username", equalTo: PFUser.current()?.username as Any)
        tQuery.selectKeys(["descContent", "header"])
        do {
            let returnedObjects = try tQuery.findObjects()
            for object in returnedObjects {
                let header = object["header"] as! String
                keyArr.append(header)
                if let arr = object["descContent"] as! [String]? {
                    requestedDictionary[header] = arr
                    requestedList += arr
                }
            }
        } catch {
        }

I can't seem to correspond the values correctly to the rows of the tableView however, I was suggested to use an array to store the values which is what I have done with the keyArr. My problem is how do I access the contents of the keys and the corresponding values in the datasource methods?? This is what I have so far but I haven't been able to link the keys and values accordingly

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "RequestViewCell", for: indexPath) as! RequestViewCell

        cell.descLbl.text = "Your ticket has been requested by \(requestedList[indexPath.row])"
        cell.refLbl.text = "for: \(keyArr[indexPath.row])"

        cell.leftBtn.tag = (indexPath.section * 100) + indexPath.row
        cell.leftBtn.addTarget(self, action: #selector(leftClick(sender:)), for: .touchUpInside)
        cell.rightBtn.tag = (indexPath.section * 100) + indexPath.row
        cell.rightBtn.addTarget(self, action: #selector(rightClick(sender:)), for: .touchUpInside)

        return cell
    }

Solution

  • You can turn dictionary into tableView representable data this way.

    let requestedDictionary:[String: [String]] = [
        "Key-1":["Value-1","Value-2","Value-3","Value-4"],
        "Key-A":["Value-X","Value-Y","Value-Z"],
        "Key-a":["Value-x","Value-y"],
    ]
    lazy var data:[(key:String,values:[String])] = requestedDictionary.compactMap({(key:$0,values:$1)})
    
    func numberOfSections(in tableView: UITableView) -> Int {
        data.count
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data[section].values.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        cell.textLabel?.text = data[indexPath.section].values[indexPath.row]
        return cell
    }
    
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return data[section].key
    }
    

    Hope it helps.