索引超出范围自定义单元格TableViewController

时间:2019-05-14 05:53:25

标签: swift uitableview

我正在尝试将3个自定义单元格填充到TableViewController中。 但我总是得到索引超出范围的错误。我不确定我的代码有什么问题。任何人都可以帮助我,我是新手。

但是当我将0用于numberOfRowsInSection返回时,输出是第一个单元格。

这是我的代码:

class testResize: UITableViewController {

    @objc var comments = [AnyObject]()
    @objc var images = [UIImage]()
    var getImg = [String]()

    override func viewDidLoad() {
        super.viewDidLoad()
        loadPosts()

        tableView.estimatedRowHeight = 100
        tableView.rowHeight = UITableViewAutomaticDimension
    }

    override func numberOfSections(in tableView: UITableView) -> Int {

        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return 3
    }

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

        if indexPath.row == 0 {
            let getCom = comments[indexPath.row]
            let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: testResizeHeadCell.self), for: indexPath) as! testResizeHeadCell
            let user = getCom["nickname"] as! String
            let ava = getCom["ava"] as! String

            if ava != "" {
                let resource = ImageResource(downloadURL: URL(string: ava)!, cacheKey: ava)
                cell.avaImg.kf.setImage(with: resource)
            }

            cell.username.text = user

            return cell
        }else if indexPath.row == 1 {
            let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: testResizeCell.self), for: indexPath) as! testResizeCell

            cell.setCustomImage(image: images[indexPath.row])

            return cell
        }else {
            let getCom = comments[indexPath.row]
            let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: testRezieTextCell.self), for: indexPath) as! testRezieTextCell
            let text = getCom["text"] as! String

            cell.explaination.text = text

            return cell
        }
    }

这是我的加载函数:

@objc func loadPosts() {
        let uuid = "959D1073"
        let url = URL(string: "some/url.php")!
        self.tableView.reloadData()
        var request = URLRequest(url: url)
        request.httpMethod = "POST"

        let body = "uuid=\(uuid)"
        //print(body)
        request.httpBody = body.data(using: String.Encoding.utf8)

        URLSession.shared.dataTask(with: request) { data, response, error in
            DispatchQueue.main.async(execute:  {
                if error == nil {
                    do{
                        let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary

                        self.comments.removeAll(keepingCapacity: false)
                        self.images.removeAll(keepingCapacity: false)
                        self.tableView.reloadData()

                        guard let parseJSON = json else {
                            print("Error While Parsing")
                            return
                        }

                        guard let posts = parseJSON["posts"] as? [AnyObject] else {
                            print("Error while parseJSONing")
                            return
                        }

                        self.comments = posts.reversed()
                        print(self.comments)
                        for i in 0 ..< self.comments.count {
                            let path = self.comments[i]["path"] as? String
                            self.getImg = [path!]
                            if !path!.isEmpty {
                                let url = NSURL(string: path!)!
                                let imageData = try? Data(contentsOf: url as URL)
                                let image = UIImage(data: imageData! as Data)!
                                self.images.append(image)
                            } else {
                                let image = UIImage()
                                self.images.append(image)
                            }
                        }
                        self.tableView.reloadData()
                        //print(posts)
                    } catch {
                        print(error)
                    }
                }else{
                    print(error!)
                }
            })
        }.resume()
    }

3 个答案:

答案 0 :(得分:0)

我假设您异步加载帖子。 但是,您不会检查数组中实际上是否有足够的元素。在使用固定索引访问数组之前,应检查数组中实际上是否有足够的元素。

此外,您应该将numberOfRows方法更改为以下内容:

ionViewDidEnter


 ionViewDidEnter(){

    this.content.scrollToBottom();

 }

加载帖子后,您可以致电

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

答案 1 :(得分:0)

我认为您只有一个注释和3个单元格类型,并且当您使用indexPath.row时,会发生类似这样的事情:

例如: 评论= {[{昵称:“ mahdi”,ava:“ url”}]}

    if indexPath.row == 0 {
        let getCom = comments[0]
        let user = getCom["nickname"] as! String
        let ava = getCom["ava"] as! String
    }else if indexPath.row == 1 {
      images[1]
    }else {
        let getCom = comments[2]
        let text = getCom["text"] as! String
    }

但是您只有一条评论,当您调用评论[1]或命令[2]时,您会得到索引超出范围错误

请尝试以下代码:

class testResize:UITableViewController {

    @objc var comments = [AnyObject]()
    @objc var images = [UIImage]()
    var getImg = [String]()

    override func viewDidLoad() {
        super.viewDidLoad()
        loadPosts()

        tableView.estimatedRowHeight = 100
        tableView.rowHeight = UITableViewAutomaticDimension
    }

    override func numberOfSections(in tableView: UITableView) -> Int {

        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return (self.comments.count == 0 ? 0 : self.comments.count + 2)
    }

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

        if indexPath.row == 0 {
            let getCom = comments[indexPath.row]
            let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: testResizeHeadCell.self), for: indexPath) as! testResizeHeadCell
            let user = getCom["nickname"] as! String
            let ava = getCom["ava"] as! String

            if ava != "" {
                let resource = ImageResource(downloadURL: URL(string: ava)!, cacheKey: ava)
                cell.avaImg.kf.setImage(with: resource)
            }

            cell.username.text = user

            return cell
        }else if indexPath.row == 1 {
            let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: testResizeCell.self), for: indexPath) as! testResizeCell

            cell.setCustomImage(image: images[indexPath.row - 1])

            return cell
        }else {
            let getCom = comments[indexPath.row - 2]
            let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: testRezieTextCell.self), for: indexPath) as! testRezieTextCell
            let text = getCom["text"] as! String

            cell.explaination.text = text

            return cell
        }
    }

并更改您的numberOfRowInSection:

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
    return (self.comments.count == 0 ? 0 : self.comments.count + 2)
}

答案 2 :(得分:0)

您做错了什么,您创建了三个数组。

@objc var comments = [AnyObject]()
@objc var images = [UIImage]()
var getImg = [String]()

您需要创建structclass。因此,您可以将所有值存储在一个地方,为什么要创建像@objc var images = [UIImage]()这样的变量,而这是快速进行操作的完全错误的方法。

现在转到numberOfRowsInSectioncellForRowAt,您将以numberOfRowsInSection返回3个单元格,但是如果看到代码,则以cellForRowAt方法返回

  if indexPath.row == 0 {
        let getCom = comments[indexPath.row] // here you return all data in comments which is more than 3 
        let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: testResizeHeadCell.self), for: indexPath) as! testResizeHeadCell
        let user = getCom["nickname"] as! String
        let ava = getCom["ava"] as! String

        if ava != "" {
            let resource = ImageResource(downloadURL: URL(string: ava)!, cacheKey: ava)
            cell.avaImg.kf.setImage(with: resource)
        }

        cell.username.text = user

        return cell
    }else if indexPath.row == 1 {
        let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: testResizeCell.self), for: indexPath) as! testResizeCell

        cell.setCustomImage(image: images[indexPath.row]) // The same mistake you did here. here you return all data of images which is more than 3 or less than 3

        return cell
    }else {
        let getCom = comments[indexPath.row]  // The same mistake you did here too. here you return all data of comments which is more than 3 or less than 3
        let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: testRezieTextCell.self), for: indexPath) as! testRezieTextCell
        let text = getCom["text"] as! String

        cell.explaination.text = text

        return cell
    }

所以它总是会给你错误

  

索引超出范围

您需要做的是创建一个Struct,并在tableView中使用它来重新加载数据。

作为参考,请参阅本教程

https://www.journaldev.com/21839/ios-swift-json-parsing-tutorial

并检查这些答案

Swift 4: Array index out of Range

How to solve Fatal error: Index out of range in Swift IOS

Swift 4 - Fatal error: Index out of range

相关问题