【问题标题】:How to populate UICollectionView with array of data?如何用数据数组填充 UICollectionView?
【发布时间】:2020-06-21 22:23:43
【问题描述】:

我有一个 UICollectionView,我使用来自 AWS Amplify List Query 函数的数据进行填充。该函数的数据数组成功打印到控制台,但它只返回 1 个单元格,其中包含来自一个 authuserPost 的元素和相应的字段。我已将结构 UserPostData 设置为等于 posts 数组中的元素。我的问题是我的 for 循环只获取一篇文章的数据,并且当应该有 5 个单元格时只显示一个单元格。但是,当我print(element) 时,它会显示所有 5 篇带有自己元素的帖子。谁能指出我做错了什么的正确方向?

这是我的代码:

import UIKit
import Amplify
import AmplifyPlugins
import AWSMobileClient

struct UserPostData {
    var id: String?
    var userSub: String?
    var zipcode: String?
    var contactMethod: String?
    
}

class UserPostsViewController: UIViewController {
    
    var userSubID = String()
    var numberOfPosts = Int(0)
    var data = [UserPostData]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        fetchData()
        setupUI()
    }
    
    lazy var collectionView: UICollectionView = {
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: collectionViewLayout())
        collectionView.register(CollectionViewCell.self, forCellWithReuseIdentifier: "CollectionViewCell")
        collectionView.backgroundColor = .tertiarySystemBackground
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        return collectionView
    }()
    
    func fetchData(){
        userSubID = AWSMobileClient.default().userSub!
        let post = authuserPost.keys
        let predicate = post.userSub == userSubID
        _ = Amplify.API.query(request: .list(authuserPost.self, where: predicate)) { event in
            switch event {
            case .success(let result):
                switch result {
                case .success(let posts):
                    DispatchQueue.main.async {
                        self.numberOfPosts = posts.count
                        self.collectionView.reloadData()
                        
                        for element in posts{
                            self.data = [UserPostData.init(id: element.id, userSub: element.userSub, zipcode: element.zipcode, contactMethod: element.contactMethod)]
                            print(element) //When I print element it shows all post and their elements. The Output will be at the bottom of the question.
                            
                        }
                        
                        //print("Successfully retrieved list of posts: \(posts)")
                    }
                case .failure(let error):
                    print("Got failed result with \(error.errorDescription)")
                }
            case .failure(let error):
                print("Got failed event with error \(error)")
            }
        }
        
    }
    
}

// MARK: - UICollectionViewDelegate & Data Source
extension UserPostsViewController: UICollectionViewDelegate, UICollectionViewDataSource {
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return data.count // It only returns one cell
        
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as! CollectionViewCell
        cell.dogImageView.image = UIImage(named: "image1")
        cell.zipcodeLabel.text = data[indexPath.section].zipcode
        cell.contactMethod.text = data[indexPath.section].contactMethod
        cell.layoutSubviews()
        return cell
    }
    
}

当我在 for 循环中 print(element) 时,我会将它发送到控制台。

authuserPost(id: "0600D60E-2270-4B1A-AE8C-7E42F2B32F9C", userSub: "47bcd9ba-78f9-4d2f-9685-8a97b3a69e77", zipcode: "30316", contactMethod: "(444)085-5666")
authuserPost(id: "6FDD8A2D-D6A6-4CDC-AD05-5D5E085178DD", userSub: "47bcd9ba-78f9-4d2f-9685-8a97b3a69e77",  zipcode: "30308", contactMethod: "(444)869-6665")
authuserPost(id: "58A3431C-7AAE-4AB0-B89E-87D932C09017", userSub: "47bcd9ba-78f9-4d2f-9685-8a97b3a69e77", zipcode: "30316", contactMethod: "(444)869-4534")
authuserPost(id: "C9DF31BE-6FC0-410C-90EE-24E13617199F", userSub: "47bcd9ba-78f9-4d2f-9685-8a97b3a69e77", zipcode: "30316", contactMethod: "(444)869-4534")
authuserPost(id: "5BD76C91-7D3A-424B-99F7-6330EE0AD6AF", userSub: "47bcd9ba-78f9-4d2f-9685-8a97b3a69e77", zipcode: "30316", contactMethod: "(444)869-3453")

【问题讨论】:

  • 你设置了collectionview的委托方法“cellForItem(at:)”吗? developer.apple.com/documentation/uikit/uicollectionview/…。那是您动态设置单元格的地方
  • @GabrielPires 对不起,我忘了提到我有这个,我把它添加到编辑过的问题中。我的问题是从数组中取出元素。
  • 哦,不用担心。您对“posts”数组的声明如何?您需要在case .success switch case 中分配它:在 reloadData() 调用之前设置如下:self.posts = posts
  • @GabrielPires 除了这个函数,我没有在其他任何地方声明postsposts 来自 AWS 后端 DynamoDB 表。
  • 哦,我明白了,这很有趣。 UserPost 有哪些属性?你应该在类的顶部创建一个变量var userPosts: UserPost。然后在您的case .success(let posts):...中分配self.userPosts = posts。然后您可以在下面的cellForItemAt: 方法中使用 userPosts。这有意义吗?

标签: swift aws-amplify


【解决方案1】:

当您遍历帖子数组并将 [UserPostData.init(...)] 分配给它时,您实际上是在一遍又一遍地重新分配 self.data 属性。只有最后一个会存活下来。

因此,您应该为迭代中的每个帖子附加 UserPostData,而不是分配给数组。


你应该替换

self.data = [UserPostData.init(id: element.id, userSub: element.userSub, zipcode: element.zipcode, contactMethod: element.contactMethod)]

self.data.append(UserPostData.init(id: element.id, userSub: element.userSub, zipcode: element.zipcode, contactMethod: element.contactMethod))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-31
    • 1970-01-01
    • 2011-01-25
    • 2016-12-27
    • 1970-01-01
    • 1970-01-01
    • 2017-10-08
    相关资源
    最近更新 更多