Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
196 views
in Technique[技术] by (71.8m points)

ios - Swift: fatal error: Index out of range

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

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

1 Reply

0 votes
by (71.8m points)

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"
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...