【问题标题】:How to load data async from firebase and display it in UICollectionView如何从 firebase 异步加载数据并在 UICollectionView 中显示
【发布时间】:2019-01-18 00:45:26
【问题描述】:

我尝试显示登录用户所关注的用户的用户名。仅详细说明那些在简单的 UICollectionView 中也有故事(如 Snapchat)的人。 所以我需要那个人的用户名在那个单元格中显示为一个简单的标签。 为此,我认为我可以简单地将所有有故事的人添加到一个数组中,然后为第一个故事获取第一个项目,为第二个故事获取第二个项目,依此类推...... 但正如我之前提到的,我想检索并显示用户名。现在的问题是“cellForItemAt”函数没有等待数组被从firebase检索到的数据填充,所以它使用空的self.storyNames数组并且return self.storyNames.count也等于0。

class HomeViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {

    @IBOutlet weak var collectionView_stories: UICollectionView!

    var storyNames: [String] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        collectionView_stories.delegate = self
        collectionView_stories.dataSource = self
        collectionView_stories.showsHorizontalScrollIndicator = false

        getStoryNames() { storyNames in
            self.storyNames = storyNames
            DispatchQueue.main.async {
                self.collectionView_stories.reloadData()
            }
        }
    }

    @IBAction func barButton_camera_pressed(_ sender: Any) {
    }

    @IBAction func barButton_inbox_pressed(_ sender: Any) {
    }

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let story_cell = collectionView_stories.dequeueReusableCell(withReuseIdentifier: "stories_cell", for: indexPath) as? StoryCollectionViewCell

        story_cell?.imageView_story.layer.cornerRadius = (story_cell?.imageView_story.frame.size.width)! / 2
        story_cell?.imageView_story.clipsToBounds = true
        story_cell?.imageView_story.layer.shadowColor = UIColor.black.cgColor
        story_cell?.imageView_story.layer.shadowRadius = 3
        story_cell?.imageView_story.layer.shadowOpacity = 0.6
        story_cell?.imageView_story.layer.borderWidth = 1.0
        story_cell?.imageView_story.layer.borderColor = UIColor.darkGray.cgColor
        story_cell?.imageView_story.image = UIImage(named: "bitmoji")

        story_cell?.label_username.text = self.storyNames[indexPath.row]

        return story_cell!
    }

    func getStoryNames(completion: @escaping ([String]) -> ()) {
        var tempStoryNames: [String] = []
        let userID = Auth.auth().currentUser?.uid
        Database.database().reference().child("subscriptions").child(userID!).observeSingleEvent(of: .value) { snapshot in
            let dispatchGroup = DispatchGroup()
            for child in snapshot.children.allObjects as! [DataSnapshot] {
                let dict = child.value as! String
                Database.database().reference().child("users").child(dict).child("hasStory").observeSingleEvent(of: .value) { snapshot in
                    if let item = snapshot.value as? Bool {
                        if (item == true) {
                            dispatchGroup.enter()
                            Database.database().reference().child("users").child(dict).child("username").observeSingleEvent(of: .value) { snapshot in
                                let aaa = snapshot.value as! String
                                tempStoryNames.append(aaa)
                                print(tempStoryNames)
                            }
                        }
                    }
                    dispatchGroup.leave()
                }
            }
            dispatchGroup.notify(queue: .main) {
                completion(tempStoryNames)
            }
        }
    }
}

你知道如何解决这个问题吗?我尽了最大努力,也知道这不是最好的代码,但我正在努力,因此我真的需要你的帮助。我感谢每一个答案!

【问题讨论】:

  • 你能看到 tempStoryNames 吗?如果在 numberOfItemsInSection 处设置断点,storyCounter 是什么,storyNames 是什么?继续。同样,什么是storyCounter,什么是storyNames?您可以在 lldb 调试部分 po storyCounter。
  • @Mocha 基本上这个数组是正确创建的,这意味着完成后的 self.storyNames 数组看起来像这样 ["firstName", "secondName"]。唯一的问题是“func cellForItemAt”没有等待检索完成,所以它需要空的self.storyNames数组。

标签: swift firebase asynchronous firebase-realtime-database uicollectionview


【解决方案1】:

numberOfItemsInSection你应该依赖storyNames的长度,这样可以确保你的数据正确显示

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

【讨论】:

  • 谢谢!这是使我的代码不那么复杂的一个非常简单的解决方案。但是现在究竟是什么问题(具体问题在 cmets 部分中说明)?
【解决方案2】:

您如何知道您的 cellForItemAt 方法有一个空的 storyNames 数组是没有意义的,因为如果您的 storyNames.count 为 0,则永远无法到达 cellForItemAt 方法。 CellForItemAt 仅在该部分中有多个项目时才被调用。

您能否在完成处理程序中放置一个断点来查看您是否返回了正确的故事名称?

    getStoryNames() { storyNames in
        self.storyNames = storyNames // breakpoint here to see if actual data
        DispatchQueue.main.async {
            self.collectionView_stories.reloadData() // breakpoint here to see if storyNames still empty
        }
    }

如果您的 cellForItemAt 方法确实被调用,那么我认为您应该调试该方法。你从来没有注册你的 stories_cell 标识符,所以可能就是这样?

【讨论】:

    猜你喜欢
    • 2021-01-03
    • 2011-06-24
    • 2018-11-27
    • 2021-03-14
    • 1970-01-01
    • 1970-01-01
    • 2019-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多