【问题标题】:Swift - display UICollectionView after retrieving dataSwift - 检索数据后显示 UICollectionView
【发布时间】:2020-04-30 13:25:36
【问题描述】:

我有一个collectionView,我通过从我的 Firestore 数据库中检索数据来填充它。我的问题是我想检索数据,并且只有在完成 collectionView 之后才会出现在 willDisplay 内部处理的动画。

这就是我检索数据的方式:

func getWishlists() {
    let db = Firestore.firestore()
    let userID = Auth.auth().currentUser!.uid
    db.collection("users").document(userID).collection("wishlists").order(by: "listIDX").getDocuments() { ( querySnapshot, error) in
        if let error = error {
            print(error.localizedDescription)
        }else {
            // get all documents from "wishlists"-collection and save attributes
            for document in querySnapshot!.documents {
                let documentData = document.data()
                let listName = documentData["name"]
                let listImageIDX = documentData["imageIDX"]

                // if-case for Main Wishlist
                if listImageIDX as? Int == nil {
                    self.dataSourceArray.append(Wishlist(name: listName as! String, image: UIImage(named: "iconRoundedImage")!, wishData: [Wish](), color: self.mainColor))
                    // set the drop down menu's options
                    self.dropDownButton.dropView.dropDownOptions.append(listName as! String)
                    self.dropDownButton.dropView.dropDownListImages.append(UIImage(named: "iconRoundedImage")!)
                }else {

                    self.dataSourceArray.append(Wishlist(name: listName as! String, image: self.images[listImageIDX as! Int], wishData: [Wish](), color: self.customColors[listImageIDX as! Int]))

                    self.dropDownButton.dropView.dropDownOptions.append(listName as! String)
                    self.dropDownButton.dropView.dropDownListImages.append(self.images[listImageIDX as! Int])
                }

                // reload collectionView and tableView
                self.theCollectionView.reloadData()
                self.dropDownButton.dropView.tableView.reloadData()

            }
        }
        self.getWishes()
    }
}

我在viewDidLoad 内部调用getWishlists,这就是我处理collectionView 的方式:

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    // return 1 more than our data array (the extra one will be the "add item" cell)
    return dataSourceArray.count + 1
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    // if indexPath.item is less than data count, return a "Content" cell
    if indexPath.item < dataSourceArray.count {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ContentCell", for: indexPath) as! ContentCell
        // set cell label
        cell.cellLabel.text = dataSourceArray[indexPath.item].name
        // set cell image
        cell.wishlistImage.image = dataSourceArray[indexPath.item].image          
        // set background color
        cell.imageView.backgroundColor = dataSourceArray[indexPath.item].color
        cell.wishCounterView.backgroundColor = dataSourceArray[indexPath.item].color
        cell.priceView.backgroundColor = dataSourceArray[indexPath.item].color



        cell.customWishlistTapCallback = {

            let heroID = "wishlistImageIDX\(indexPath)"
            cell.theView.heroID = heroID

            let addButtonHeroID = "addWishButtonID"
            self.addButton.heroID = addButtonHeroID     

            let vc = self.storyboard?.instantiateViewController(withIdentifier: "WishlistVC") as! WishlistViewController            

            vc.theTableView.tableView.reloadData()
            self.present(vc, animated: true, completion: nil)

        }

        return cell
    }

    // past the end of the data count, so return an "Add Item" cell
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "AddItemCell", for: indexPath) as! AddItemCell

    // set the closure
    cell.tapCallback = {

        self.listNameTextfield.becomeFirstResponder()

        // let newListView appear
        UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseOut, animations: {
            self.blurrImage.alpha = 0.96
            self.blurrImage.transform = CGAffineTransform(translationX: 0, y: 0)
            self.newListView.transform = CGAffineTransform(translationX: 0, y: 0)
            self.view.layoutIfNeeded()
        })

        self.appWillEnterForegroundHandler()

    }

    return cell

}

// animate displaying cells
func collectionView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    // Add animations here
    cell.alpha = 0

    UIView.animate(
        withDuration: 0.5,
        delay: 0.05 * Double(indexPath.row),
        animations: {
            cell.alpha = 1
    }) 
}

目前,单元格没有被动画化,而是在检索数据时稍等片刻后才显示出来。

【问题讨论】:

    标签: ios swift firebase google-cloud-firestore uicollectionview


    【解决方案1】:

    willDisplay 是 pul 动画的正确位置;但是,它仅在您设置委托时才会触发。看起来您查看了数据源,否则您什么也看不到。设置委托和断点 willDisplay 以验证其被调用。

    【讨论】:

    • 我必须添加什么代表?我在willDisplay 内使用print 对其进行了测试,但它没有被调用
    • UICollectionViewDelegate 如:collectionView.delegate=self
    • 啊对。它现在实际上是正确的动画。不过还是有一点小问题。如果您查看代码,collectionView 中的最后一个celladdItemCell,而cell 没有任何检索到的数据,所以它在开始时就在那里。有没有办法只显示整个collectoinView,直到收到所有数据?
    • 是的,只需设置collectionView.isHidden = true,当您的请求返回时,其非空设置collectionView.isHidden = false
    • 制作一个类似shouldAnimateCells = true 的标志并在您的 willDisplay 方法中添加一个guard shouldAnimate else {return},然后在委托方法scrollViewWillBeginDragging 中,如果您有数据(即如果他们滚动一个空视图不要设置标志)。
    猜你喜欢
    • 1970-01-01
    • 2020-04-08
    • 2015-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-14
    • 2015-01-25
    相关资源
    最近更新 更多