Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm getting an "Index out of range" when populating a UITableView. I don't know why it gives me error. I have a condition statement on my cell creation function which checks for the count of each array and then adds a custom cell on index 0.

If anyone knows about this problem, please tell me the solution. I've been working on it for days and can't seem to figure this one out.

var homeArr: [services] = []
var autoArr: [services] = []

Alamofire.request(url_specialist_request_url, method: .post, parameters: parameters).responseJSON {
    response in

    if response.data != nil {
        let json = JSON(data: response.data!)
        let json_count = json.count

        // print(json)

        self.homeArr.append(services(service_name:"",service_icon:"",service_category:""))
        self.autoArr.append(services(service_name:"",service_icon:"",service_category:""))
        self.personalArr.append(services(service_name:"",service_icon:"",service_category:""))

        for i in 0 ..< json_count {
            let categoryId = json[i]["category_id"].string!
            if(categoryId == "1") {
                self.homeArr.append(services(service_name:json[i]["service_name"].string!,service_icon:"(json[i]["service_icon"].string!)Icon",service_category:json[i]["category_id"].string!))
            } else if(categoryId == "2") {
                self.autoArr.append(services(service_name:json[i]["service_name"].string!,service_icon:"(json[i]["service_icon"].string!)Icon",service_category:json[i]["category_id"].string!))
            } else {
                self.personalArr.append(services(service_name:json[i]["service_name"].string!,service_icon:"(json[i]["service_icon"].string!)Icon",service_category:json[i]["category_id"].string!))
            }
        }

        self.tableView.reloadData()
    }
}

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

    let home_dict = self.homeArr[indexPath.row]
    // ** Index out of range on the following line **
    let auto_dict = self.autoArr[indexPath.row]

    if(self.homeArr.count > 1) {
        if (indexPath.row == 0)
        {
            cell.serviceLabel!.text = "Home"
            cell.contentView.backgroundColor = UIColor.blue
        } else {
            cell.serviceLabel!.text = home_dict.service_name
            cell.serviceIcon!.image = UIImage(named:"(home_dict.service_icon)")
        }
    }

    if(self.autoArr.count > 1) {
        if (indexPath.row == 0)
        {
            cell.serviceLabel!.text = "Personal"
            cell.contentView.backgroundColor = UIColor.blue
        } else {
            cell.serviceLabel!.text = auto_dict.service_name
            cell.serviceIcon!.image = UIImage(named:"(auto_dict.service_icon)")
        }
    }

    return cell
}

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

This is what I want to achieve

    Home Arr cell

value1 value2
    Auto Arr cell

value1 value2 See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
190 views
Welcome To Ask or Share your Answers For Others

1 Answer

Create two sections One for HomeArr and one for AutoArr. I believe for each section you wanna show a additional cell with some title. So below code should help you.

extension ViewController : UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if section == 0 {
            return (homeArr.count > 0) ?  homeArr.count + 1 : 0
        }
        else {
            return (autoArr.count > 0) ?  autoArr.count + 1 : 0
        }
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "serviceCell",for:indexPath) as! servicesCell
        if indexPath.section == 0 {
            if (indexPath.row == 0)
            {
                cell.serviceLabel!.text = "Home"
                cell.contentView.backgroundColor = UIColor.blue
            } else {
                let home_dict = self.homeArr[indexPath.row - 1]
                cell.serviceLabel!.text = home_dict.service_name
                cell.serviceIcon!.image = UIImage(named:"(home_dict.service_icon)")
            }
        }
        else {
            if (indexPath.row == 0)
            {
                cell.serviceLabel!.text = "Personal"
                cell.contentView.backgroundColor = UIColor.blue
            } else {
                let auto_dict = self.autoArr[indexPath.row - 1]
                cell.serviceLabel!.text = auto_dict.service_name
                cell.serviceIcon!.image = UIImage(named:"(auto_dict.service_icon)")
            }
        }
        return cell
    }
}

EDIT:

As pointed out by rmaddy in comments below

Why the extra row in each section? Why not use a section header instead?

As we are not aware of OP's exact requirement I am updating my code to show section title as well.

 extension ViewController : UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if section == 0 {
            return homeArr.count
        }
        else {
            return autoArr.count
        }
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "serviceCell",for:indexPath) as! servicesCell
        if indexPath.section == 0 {
            let home_dict = self.homeArr[indexPath.row]
            cell.serviceLabel!.text = home_dict.service_name
            cell.serviceIcon!.image = UIImage(named:"(home_dict.service_icon)")
        }
        else {
            let auto_dict = self.autoArr[indexPath.row]
            cell.serviceLabel!.text = auto_dict.service_name
            cell.serviceIcon!.image = UIImage(named:"(auto_dict.service_icon)")
        }
        return cell
    }

    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        if section == 0 {
            return "Home Arr cell"
        }
        else {
            return "Auto Arr cell"
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...