UICollectionView выдает ошибку «Индекс вне диапазона» - PullRequest
0 голосов
/ 28 октября 2018

Это вопрос.В настоящее время я хотел бы отобразить UITableViewCell в UITableView для количества пользователей, зарегистрированных в базе данных.Однако он становится «Индекс вне диапазона» в методе UITableViewDataSOurce (cellForItemAt).Я понимаю значение ошибки, но не знаю, почему возникает такая ошибка.Не могли бы вы сказать мне?

import UIKit
import Firebase
import FirebaseStorage
import FirebaseFirestore
import SDWebImage

struct MemberData {
  var image: URL?
  var text: String?
}

class MemberSelectViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
  let statusBsr = UIApplication.shared.statusBarFrame.height

  let db = Firestore.firestore()
  var teamIDFromFirebase: String = ""
  var fireAuthUID = (Auth.auth().currentUser?.uid ?? "no data")
  var memberData = [MemberData]()

  var memberImageArr = [Any]()
  var memberTextArr = [Any]()
  var memberUserIDArr = [Any]()

  override func viewDidLoad() {
      super.viewDidLoad()

      let collectionView = UICollectionView(frame: CGRect(x: 0, y: statusBsr, width: self.view.frame.width, height: self.view.frame.size.height - statusBsr), collectionViewLayout: UICollectionViewFlowLayout())

      let nibName = UINib(nibName: "memberCollectionViewCell", bundle: nil)
      collectionView.register(nibName, forCellWithReuseIdentifier: "memberCell")

      collectionView.delegate = self
      collectionView.dataSource = self

      self.view.addSubview(collectionView)
      getMemberData(collectionView: collectionView)
  }

  func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
      return 24
  }

  func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
      let size = self.view.frame.size.width / 4
      return CGSize(width: size, height: size)
  }

  func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {

      let inset =  (self.view.frame.width / 4) / 5

      return UIEdgeInsets(top: inset, left: inset, bottom: inset, right: inset)
  }

  func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
      return (self.view.frame.width / 4) / 5
  }

  func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
      let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "memberCell", for: indexPath) as! memberCollectionViewCell
          let cellData = memberData[indexPath.row]
          cell.memberImage.sd_setImage(with: cellData.image)
          cell.memberTitle.text = cellData.text
      return cell
  }
}


private extension MemberSelectViewController {
    private func getMemberData(collectionView: UICollectionView) {
    self.db.collection("users").document(self.fireAuthUID).addSnapshotListener { (snapshot3, error) in
        guard let document3 = snapshot3 else {
            print("erorr2 \(String(describing: error))")
            return
        }
        guard let data = document3.data() else { return }
        self.teamIDFromFirebase = data["teamID"] as? String ?? ""
        self.db.collection("users").whereField("teamID", isEqualTo: self.teamIDFromFirebase).getDocuments() { (querySnapshot, err) in
            if let err = err {
                print("Error getting documents: \(err)")
                return
            } else {
                var i = 0
                for document in querySnapshot!.documents {
                    guard var documentData: [String: Any] = document.data() else { return }
                    self.memberImageArr.append((documentData["image"] as? String)!)
                    self.memberTextArr.append((documentData["name"] as? String)!)
                    self.memberData.append(MemberData(image: URL(string: self.memberImageArr[i] as! String), text: self.memberTextArr[i] as! String))
                    i += 1
                }
            }
        }
    }
}
}

1 Ответ

0 голосов
/ 28 октября 2018

В этом методе

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
  return 24
}

Вы сообщаете представлению коллекции, что всегда будет 24 строки, поэтому, когда представление загружается, оно начнет получать содержимое для 24 строк в представлении коллекции.

Однако ваш массив memberData определен следующим образом:

var memberData = [MemberData]()

Это означает, что изначально он будет пустым.

Затем вы начнете добавлять содержимое к memberData в getMemberData, но в этот момент представление вашей коллекции, возможно, уже начало заполняться и запрашивает содержимое для строки номер 5 (например) ... в массиве без элементов, и это приведет к сбою.

Итакто, что вы можете сделать, это:

  1. Изменить numberOfItemsInSection на не вернуть статическое значение, но вместо этого вернуть фактическое количество элементов в вашем memberData примерно так:

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return memberData.count
    }
    

    как только вы закончите загрузку данных в memberData в функции getMemberData, вы даете команду представлению коллекции перезагрузиться, и он будет проходить через весь процесс построения представления вашей коллекции снова,на этот раз с данными.

  2. в cellForItemAt вы можете убедиться, что не пытаетесь получить контент, которого там нет:

    if indexPath.row < memberData.count {
        let cellData = memberData[indexPath.row
        //and so on
    }
    

Надеюсь, что это даст вам некоторые подсказки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...