【问题标题】:Swift: fatal error: Index out of rangeSwift:致命错误:索引超出范围
【发布时间】:2017-11-17 16:46:03
【问题描述】:

填充 UITableView 时出现“索引超出范围”。 我不知道为什么它会给我错误。我的单元格创建函数有一个条件语句,它检查每个数组的计数,然后在索引 0 上添加一个自定义单元格。

如果有人知道这个问题,请告诉我解决方案。我已经研究了几天,似乎无法弄清楚这一点。

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

这就是我想要实现的目标

    Home Arr 单元格

  • 值1
  • 值2
    • 自动排列单元格

  • 值1
  • 值2
  • 【问题讨论】:

    • 首先指出导致错误的确切代码行。
    • @IGNITER 你确实 return(homeArr.count + arrAuto.count) 意味着如果每个数组中有 10 个值,则行数为 20。现在在单元格方法中你正在做 self.homeArr[ indexPath.row] 和 self.autoArr[indexPath.row] 。您的数组包含 10 个索引,但方法调用 20,因此索引超出范围。
    • @TusharSharma 您认为解决方法是什么?我不知道。
    • @rmaddy 这行出错 let auto_dict = self.autoArr[indexPath.row]
    • 您希望如何在表格视图中显示您的数据?您有两个似乎想要显示的数据数组。您是否希望homeArr 中的每个值对应一行,autoArr 中的每个值对应一行?您想在homeArr 的行之后显示autoArr 的所有行吗?请说明你的目标。

    标签: ios arrays swift indexing


    【解决方案1】:

    创建两个部分,一个用于 HomeArr,一个用于 AutoArr。我相信对于每个部分,您都想显示一个带有某些标题的附加单元格。所以下面的代码应该可以帮助你。

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

    编辑:

    正如rmaddy 在下面的 cmets 中指出的那样

    为什么每个部分都多出一行?为什么不使用节标题 代替?

    由于我们不知道 OP 的确切要求,我正在更新我的代码以显示部分标题。

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

    【讨论】:

    • 为什么每个部分都多出一行?为什么不使用节标题呢?
    • @rmaddy : OP 没有发布任何显示他要求的图片。在他的代码中,OP 添加了一个新单元格,因此假设他不需要节标题并需要无缝单元格流。不确定要求完全因此添加。
    • @rmaddy :尝试将代码更改保持在最低限度。因为他已经添加了一个 if 条件来检查 row == 0 所以我认为 Ill not return a section header.
    • 希望 OP 最终能够回答我关于他们希望如何显示数组数据的问题,但到目前为止,还没有运气。
    • @rmaddy :无论如何我都会更新我的答案以反映您对部分标题的建议:)
    猜你喜欢
    • 1970-01-01
    • 2016-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多