如何使用 Swift 4 解决 Tableview 数据数组“超出范围值”?

Posted

技术标签:

【中文标题】如何使用 Swift 4 解决 Tableview 数据数组“超出范围值”?【英文标题】:How to solve Tableview data array "Out of range values" using Swift 4? 【发布时间】:2018-08-07 14:20:10 【问题描述】:

我的场景我使用多个数组作为多个单元格标签。我正在维护每个单元格两个不同的标签。我为单元标签分配了单独的数组。

喜欢:

cell.accessibilityValue = String(id[indexPath.row])
cell.name_Label.text = name[indexPath.row]
cell.city_Label.text = city[indexPath.row] 

在这里,我从 JSON 中获取并单独附加的所有数组值。我将只显示名称和城市,但 cell.accessibilityValue "ID" 我试图将该 ID 存储在 cell.accessibilityValue 中,因为我在单元格 ADDPlus 中维护两个按钮。 First Add 将显示,一旦用户单击该添加按钮,它将调用 JSON 并获取 ID 值,之后只有 ID 值附加在 cell.accessibilityValue = String(id[indexPath.row]) 中,然后我也会重新加载。

我面临的问题:

    最初没有值 cell.accessibilityValue = String(id[indexPath.row]) 所以我是 超出范围错误。 添加按钮后,我尝试将 ID 值附加到 id 数组中 它应该分配到我的单元格中,因为单击添加后它将 隐藏并显示加号按钮,加号按钮点击获取 存储的 ID。

注意:这里的 ID 可能有机会为 null,因此如果可用的值需要分配,否则为 null。

这是我的代码

protocol CustomCellDelegate 
    func cellButtonTapped(cell: CustomOneCell)


class CustomOneCell: UITableViewCell 

    // Link those IBOutlets with the UILabels in your .XIB file
    @IBOutlet weak var name_Label: UILabel!
    @IBOutlet weak var city_Label: UILabel!
    @IBOutlet weak var add_Button: UIButton!

    var delegate: CustomCellDelegate?

    @IBAction func add_buttonTapped(_ sender: Any) 
        delegate?.cellButtonTapped(cell: self)
    


class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, CustomCellDelegate 

    var id = [Int]()        // This is from JSON but Initially no values
    var name = [String]()   // This is from JSON ["Item 1", "Item2", "Item3", "Item4"]
    var city = [String]()   // This is from JSON ["Item 1", "Item2", "Item3", "Item4"]

    override func viewDidLoad() 
        super.viewDidLoad()
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
    

    //MARK - UITableview
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return name.count
    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

        let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomOneCell

        cell.delegate = self
        cell.accessibilityValue = String(id[indexPath.row]) // #1. Initially no values, So I am getting out of range Error

        cell.name_Label.text = name[indexPath.row]
        cell.city_Label.text = city[indexPath.row]

        return cell
    

    func cellButtonTapped(cell: CustomOneCell) 

        let url = URL(string: "")!
        var request = URLRequest(url: url)
        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        request.httpMethod = "GET"
        let task = URLSession.shared.dataTask(with: request)  data, response, error in
            guard let data = data else 
                print("request failed \(error)")
                return
            
            do 
                if let json = try JSONSerialization.jsonObject(with: data) as? [[String: Any]] 
                    for item in json 

                        let id = item["id"]!
                        self.id.append(id as! Int) // #2. After table load I am appending some values into id array
                    
                    //Table reload to assign id values
                
             catch let parseError 
                print("parsing error: \(parseError)")
                let responseString = String(data: data, encoding: .utf8)
                print("raw response: \(responseString!)")
            
        
        task.resume()

    

【问题讨论】:

得到这样的错误似乎很有效。您确定三个数组的计数相同吗?此外,我强烈建议将您的数据组合在一个 Model 中(一个模型包含 id、name 和 city),而不是将它们作为单独的数组。 最初没有值,所以我超出了 ID 的范围错误,但其他两个数组数据将可用。 @艾哈迈德 我正在使用多个数组。这会导致错误。正如 Joakim 建议的那样,使用结构。它更加高效且易于维护。 【参考方案1】:

最简单的方法是在tableView:cellForRowAt 中添加范围检查

if indexPath.row < id.count 
    cell.accessibilityValue = String(id[indexPath.row])

但如果可能的话,我会考虑创建一个包含所有三个值的结构并维护一个而不是三个数组

struct SomeData 
    var id: Int
    var name: String
    var city: String

【讨论】:

对不起,我知道 struct 是一种简单的方法,但是我实现了很多行代码,所以无法再次修改。我将尝试使用您的解决方案,并在此处告知结果。谢谢@Joakim Danielson

以上是关于如何使用 Swift 4 解决 Tableview 数据数组“超出范围值”?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift Xcode 6.4 的 TableView 中显示 Parse 数组

我如何使用解码器在swift 4中解析tableview中的json数组

如何在 Swift 中使用 MagicalRecord CoreData 删除 tableview 中的记录

如何使用视图控制器重新加载 tableview (swift)

CollectionViews 和 TableView 不在 StackView 中显示 - Swift 4

如何在 swift 4 中的 tableView Cell 中创建 collectionview? [复制]