Ios 赢得的数据';t填充UICollectionView滚动视图

Ios 赢得的数据';t填充UICollectionView滚动视图,ios,swift,uicollectionview,uiscrollview,uicollectionviewcell,Ios,Swift,Uicollectionview,Uiscrollview,Uicollectionviewcell,我是新来的,所以请对我放松点 我的问题如下: 我试图用firebase中的数据填充滚动视图(UICollectionView) 我确信它正在成功地检索数据,因为我可以在firebase函数末尾使用for循环打印数据 问题是,当我尝试将数据插入滚动视图时,它会说数据超出范围 有人向我指出,scrollview中填充了我在下面显示的scrollview委托方法 还有人向我指出,我的数据源是“self.pages”。如何将从firebase检索到的数据传递给委托方法 Fatal error: Inde

我是新来的,所以请对我放松点

我的问题如下:

我试图用firebase中的数据填充滚动视图(UICollectionView)

我确信它正在成功地检索数据,因为我可以在firebase函数末尾使用for循环打印数据

问题是,当我尝试将数据插入滚动视图时,它会说数据超出范围

有人向我指出,scrollview中填充了我在下面显示的scrollview委托方法

还有人向我指出,我的数据源是“self.pages”。如何将从firebase检索到的数据传递给委托方法

Fatal error: Index out of range
这是我的密码:

//arrays of names and descriptions which are populated in firebase() function
    var names:[String] = []
    var descriptions: [String] = []
页面类:

 let imageName: UIImage
 let headerText: String
 let bodyText: String 
这是viewDidLoad

override func viewDidLoad() {
        super.viewDidLoad()

        firebase()
        setupImages()
    }
以下是图像设置功能:

 func setupImages(){

        self.pages = [
            Page(imageName: self.image, headerText: names[0], bodyText: descriptions[0]),

            Page(imageName: self.image, headerText: names[1], bodyText: descriptions[1]),

            Page(imageName: self.image, headerText: names[2], bodyText: descriptions[2]),

            Page(imageName: self.image, headerText: names[3], bodyText: descriptions[3]),

            Page(imageName: self.image, headerText: names[4], bodyText: descriptions[4]),
        ]

        self.collectionView?.backgroundColor = .white
        self.collectionView?.register(PageCell.self, forCellWithReuseIdentifier: "cellId")
        self.collectionView?.isPagingEnabled = true
    }
我认为问题是由于firebase数据检索速度不够快造成的

我之所以这样说,是因为我在另一个类中有另一个函数,它似乎在设置它:

override init(frame: CGRect) {
        super.init(frame: frame)
        //setup layout sets up constraints for the layout of the page
        setupLayout()
    }
添加UICollectionViewDataSource方法的:

override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return pages.count
    }
以及:

Firebase检索方法:

func firebase()
    {
        //connection to firebase for the names and descriptions
        let db = Firestore.firestore()
        db.collection(restaurauntName).getDocuments { (snapshot, err) in

            if let err = err {
                print("Error getting documents: \(err)")
            } else {
                for document in snapshot!.documents {
                    let name = document.get("Name") as! String
                    let description = document.get("Description") as! String
                    //Add names and descriptions to the arrays
                    self.names.append(name)
                    self.descriptions.append(description)
                }
            }

            for x in self.names{
                print(x)
            }

        }
    }

谢谢你的阅读,如果有人能帮我找到正确的方向,我将不胜感激

查看代码:您正在使用self.pages作为数据源。在您提供的代码中,我看不到与Firebase的连接

错误也可能来自传入页面时如何设置单元格

cell.page = page

要快速调试,您可以对该行进行注释,看看错误是否消失。

问题就在这里,您的假设是正确的;代码的顺序不正确

override func viewDidLoad() {
   super.viewDidLoad()

   firebase()
   setupImages()
}
Firebase是异步的,您的应用程序需要以这样的方式构建:您只需在调用后的闭包中尝试使用Firebase数据。在viewDidLoad函数中,调用firebase()加载数据,但setupImages函数将在firebase有时间从服务器获取数据之前实际执行

幸运的是,这是一个简单的解决方案。下面是一些新函数,其中包含一些更新的名称,以使流程更加清晰

override func viewDidLoad() {
   super.viewDidLoad()

   self.loadDataFromfirebase()
}
然后

func loadDataFromFirebase() {
   let db = Firestore.firestore()
   db.collection(restaurauntName).getDocuments { (snapshot, err) in
      if let err = err {
         print("Error getting documents: \(err)")
         return
      } else {
         for document in snapshot!.documents {
            let name = document.get("Name") as! String
            let description = document.get("Description") as! String
            self.names.append(name)
            self.descriptions.append(description)
         }
         self.setupImages() //safe to do this here as the firebase data is valid
         self.collectionView.reloadData()
      }
   }
}

我担心的是如果有25份文件。。。您的setupImages仅访问前5个。同样,如果有3个文档,应用程序将崩溃,因为该函数将尝试访问索引3和索引4处的对象,而这些对象将不存在。

如果您可以共享tableView委托方法和数据源,那将很好。@Kanongata我不相信我有tableView委托,您所说的数据源是什么意思?我已经展示了如何从firebase获取数据?@mike he的意思是UICollectionViewDataSource方法's@byaruhaf我在哪里能找到?如果这是一个愚蠢的问题,很抱歉?collectionView用于
numberOfItemsInSection
cellForItemAt
感谢您的回复!我已经尝试了这两种解决方案,但都没有取得任何效果:(你还有其他想法吗?为什么要投否决票?无论如何,你需要提供更多的代码。你正在尝试访问超出范围的索引。它不在你提供的代码中。不是我投了反对票,而是我现在投了你的赞成票。因为我是一个新的投稿人,我认为我的投票不算在内。有什么建议吗?)我不能为上下文添加额外的代码吗?再次感谢您的帮助OP正在使用collectionView,因此indexPath.item更常用于这些。indexPath.row更像是tableView。没错,这只是一个故障排除的想法。两个都很好。嗨,Jay,这很好!非常感谢您坚持我的观点!这是wrec我在项目的其他方面工作了好几天!我不担心只有5个文档,因为每次都会有5个文档!再次感谢!虽然是工作,但在加载内容之前屏幕变黑了?这又是一个异步问题吗?@mike screen变黑了?你能详细说明一下吗re screen变黑了,这听起来像是与您的视图或其他内容完全不同的问题。很抱歉再次打扰您!基本上,当我运行应用程序时,屏幕变黑了,就像这里的视频:@mike,看起来您的视图设置有问题。我会在这一行设置断点
setupLayout
并查看它是在之前还是之后变黑,然后从那里一行一行地遍历代码,看看是什么导致了它。
func loadDataFromFirebase() {
   let db = Firestore.firestore()
   db.collection(restaurauntName).getDocuments { (snapshot, err) in
      if let err = err {
         print("Error getting documents: \(err)")
         return
      } else {
         for document in snapshot!.documents {
            let name = document.get("Name") as! String
            let description = document.get("Description") as! String
            self.names.append(name)
            self.descriptions.append(description)
         }
         self.setupImages() //safe to do this here as the firebase data is valid
         self.collectionView.reloadData()
      }
   }
}