使用UICollectionView执行Segue时出错

时间:2018-06-17 01:48:00

标签: ios json swift uicollectionview

当我点击任何UICollectionView项时,我在PerformSegue行上出现了这个错误:

  

线程1:致命错误:索引超出范围

但是,编译器不会读取函数,只是直接跳转到PerformSegue,所以我最终没有索引。我该如何解决这个问题?当用户点击任何UICollectionView索引时,我必须替换函数参数中的Indexpath并重复该过程。

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    getCategoriaPorID(IdCategoria: indexPath.row) { (data) in
        DispatchQueue.main.async {

        self.dataCategoriaID = data
        }
    }
    performSegue(withIdentifier: "segueCategorias", sender:self.dataCategoriaID[indexPath.row])
}

完整的ViewController文件:

import UIKit

class ViewController: UIViewController, UICollectionViewDataSource, UITableViewDataSource, UITableViewDelegate, UICollectionViewDelegate {

    @IBOutlet weak var tableViewTopSell: UITableView!
    @IBOutlet var collectionView: UICollectionView!
    @IBOutlet weak var collectionViewBanner: UICollectionView!
    var indexPathId = Int()
    var dataSource: [Content] = [Content]()
    var dataBanner: [Banner] = [Banner]()
    var dataTopSold: [Top10] = [Top10]()
    var dataCategoriaID: [CategoriaIDItems] = [CategoriaIDItems]()

    override func viewDidLoad() {
        super.viewDidLoad()
        //Delegate TableView
        self.tableViewTopSell.delegate = self
        //SetupNavBarCustom
        self.navigationController?.navigationBar.CustomNavigationBar()
        let logo = UIImage(named: "tag.png")
        let imageView = UIImageView(image:logo)
        self.navigationItem.titleView = imageView
        //CallAPIData
        getTopSold { (data) in
            DispatchQueue.main.async {
                self.dataTopSold = data
                self.tableViewTopSell.reloadData()
            }
        }
        getBanner { (data) in
            DispatchQueue.main.async {
            self.dataBanner = data
            self.collectionViewBanner.reloadData()
            }
        }
        getAudiobooksAPI { (data) in
            DispatchQueue.main.async {
                self.dataSource = data
                self.collectionView.reloadData()
            }
        }
    }
    //CollectionView
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if (collectionView == self.collectionView) {
            return  self.dataSource.count
        }else{
            return self.dataBanner.count
        }}
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        if (collectionView == self.collectionView) {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell", for: indexPath) as! CollectionViewCell

        let content = self.dataSource[indexPath.item]

        cell.bookLabel.text = content.descricao
        cell.bookImage.setImage(url: content.urlImagem, placeholder: "")

        return cell

        }else if (collectionView == self.collectionViewBanner) {

            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCellBanner", for: indexPath) as! CollectionViewCell

            let content = self.dataBanner[indexPath.item]

            cell.bannerImage.setImage(url: content.urlImagem, placeholder: "")


            return cell
        }
        return UICollectionViewCell()
    }


    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

        getCategoriaPorID(IdCategoria: indexPath.row) { (data) in
            DispatchQueue.main.async {

            self.dataCategoriaID = data
            }
        }
        performSegue(withIdentifier: "segueCategorias", sender:self.dataCategoriaID[indexPath.row])
    }






//TableView
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.dataTopSold.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "topSoldCell", for: indexPath) as! TableViewCell

    let content = self.dataTopSold[indexPath.row]
    cell.labelNomeTopSell.text = content.nome
    cell.imageViewTopSell.setImage(url: content.urlImagem, placeholder: "")
    cell.labelPrecoDe.text = "R$ \(content.precoDe)"
    //Colocar strike em cima do Preco Antigo
    let oldPrice = "R$ \(content.precoDe)"
    let promotionString = oldPrice + ""
    let attributedStr = NSMutableAttributedString(string: promotionString)
    let crossAttr = [NSAttributedStringKey.strikethroughStyle: NSUnderlineStyle.styleSingle.rawValue]
    attributedStr.addAttributes(crossAttr, range: NSMakeRange(0, oldPrice.count))
    cell.labelPrecoDe.attributedText = attributedStr
    //
    cell.labelPrecoPor.text = "R$ 119.99"
    return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    performSegue(withIdentifier: "segueId", sender:self.dataTopSold[indexPath.row])

    }
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        if segue.identifier == "segueId" {

            let des = segue.destination as? TelaDetalheProdutos

            //.item possui uma propriedade instanciada na TelaDetalheProdutos
            des?.item = (sender as? Top10)
            //Segue para CollectionView Categorias
        } else if segue.identifier == "segueCategorias" {

            let desc = segue.destination as? TelaCategorias

            desc?.item = (sender as? CategoriaIDItems)
        }
    }

}
//Cast UIImage Extension
extension UIImageView{
    func setImage(url : String, placeholder: String, callback : (() -> Void)? = nil){
        self.image = UIImage(named: "no-photo")

        URLSession.shared.dataTask(with: NSURL(string: url)! as URL, completionHandler: { (data, response, error) -> Void in

            guard error == nil else{
                return
            }
            DispatchQueue.main.async(execute: { () -> Void in
                let image = UIImage(data: data!)
                self.image = image

                if let callback = callback{
                    callback()
                }
            })

        }).resume()
    }
}

1 个答案:

答案 0 :(得分:0)

仅使用主线程更新UI。问题是你在主线程上设置dataCategoriaID我假设哪个是异步网络调用函数。因此,您在设置dataCategoriaID之前尝试执行segue,这就是它为空并抛出index out of range错误的原因。

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

  getCategoriaPorID(IdCategoria: indexPath.row) { (data) in
    self.dataCategoriaID = data
    performSegue(withIdentifier: "segueCategorias", sender:self.dataCategoriaID[indexPath.row])
  }
}