在集合视图中合并2个类阵列

时间:2017-09-18 11:50:21

标签: arrays swift3 uicollectionview xcode8

如何在集合视图中合并2个类数组?我已经设法显示2个数组但是如何让它们交织并根据postDate追加?

下面我有一个photoPosts数组和一个videoPosts数组,我目前正在使用以下方法。但是这只显示一个接一个的数组。提前致谢

var photoPosts = [photoPost]()
var videoPosts = [videoPost]()

func retrieveData(){
let ref = Database.database().reference().child("videoPost").child(uid)
        ref.observe(.childAdded, with: { (snapshot) in
            let dictionary = videoPost(snapshot: snapshot)
            self.videoPosts.append(dictionary)
             self.videoPosts.sort(by: { (p1, p2) -> Bool in
              return p1.postDate?.compare(p2.postDate!) == .orderedDescending
                })
 })
let ref = Database.database().reference().child("photoPost").child(uid)
        ref.observe(.childAdded, with: { (snapshot) in
            let dictionary = photoPost(snapshot: snapshot)
            self. photoPosts.append(dictionary)
                self.posts.sort(by: { (p1, p2) -> Bool in
                    return p1.postDate?.compare(p2.postDate!) == .orderedDescending
                })
})
 self.newsfeedCollectionView?.reloadData()
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
 return videoPosts.count + photoPosts.count
}
       func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {         
                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! newsfeedCollectionViewCell
             if indexPath.item < photoPosts.count {
                cell. photoPost = photoPosts[indexPath.item]
               } else {
                 cell.videoPost = videoPosts[indexPath.item-photoPosts.count]
                 }
                return cell
                }

更新

let ref = Database.database().reference().child("videoPost").child(user.uid!)
        ref.observe(.value, with: { (snapshot) in

            if snapshot.exists() {

                print(snapshot)
                let array:NSArray = snapshot.children.allObjects as NSArray
                for child in array {
                    let snap = child as! DataSnapshot
                    let dictionary = videoPost(snapshot: snapshot)
                    self.arrayPosts.add(dictionary)
                }
            }

            let ref1 = Database.database().reference().child("photoPost").child(user.uid!)
            ref1.observe(.value, with: { (snapshot) in
                if snapshot.exists() {
                    let array:NSArray = snapshot.children.allObjects as NSArray
                    for child in array {
                        let snap = child as! DataSnapshot
                        let dictionary = photoPost(snapshot: snapshot)
                        self.arrayPosts.add(dictionary)
                    }
                }

                self.arrayPosts.sorted { (p1, p2) -> Bool in
                    // declare post type

                    var postDate1:NSNumber!
                    var postDate2:NSNumber!
                    // check the object type and get the date value to compare.
                    if p1 is photoPost {
                        let obj:photoPost =  p1 as! photoPost
                        postDate1 =   obj.postDate
                    }
                    if p2 is photoPost {
                        let obj:photoPost =  p1 as! photoPost
                        postDate2 =   obj.postDate
                    }

                    if p1 is videoPost {
                        let obj:videoPost =  p1 as! videoPost
                        postDate1 =   obj.postDate
                    }
                    if p2 is videoPost {
                        let obj:videoPost =  p1 as! videoPost
                        postDate2 =   obj.postDate
                    }

                    return postDate1?.compare(postDate2!) == .orderedDescending
                }


                // use arrayPosts to show data on collection view
                self.newsfeedCollectionView?.reloadData()

            })

        })

    }

1 个答案:

答案 0 :(得分:0)

好的,我创建了一个可以保存任何类型的时间轴帖子的类型。在您的问题中,您有一个VideoPost和一个PhotoPost,因此我们需要一种可以保存视频,照片和日期的类型,以便我们对其进行排序。

你可以添加其他属性,如评论,描述,喜欢等......如果你也需要它们。

struct TimelinePost {
    enum Content {
        case photo(UIImage)
        case video(URL) // I don't know how you are storing videos but I'm using URL here as an example
    }

    let date: Date
    let content: Content
}

通过这样做,您无需拥有异构数组。如果可能的话,尝试使用同类数据总是一个好主意。正如您所知,使用异构数据会变得棘手。

现在你可以使它具有可比性......

extension TimelinePost: Comparable {
    static func < (lhs: TimelinePost, rhs: TimelinePost) -> Bool {
        return lhs.date < rhs.date
    }

    static func == (lhs: TimelinePost, rhs: TimelinePost) -> Bool {
        return lhs.date == rhs.date // this is probably to correct.
        // you need to decide what it means for two posts to be equal.
    }
}

负责对数组进行排序。

现在你可以像这样转换你的数组......

let videoArray = ... // your video array
let photoArray = ... // your photo array

let timelineArray: [TimelinePost] = 
    (videoArray.map { TimelinePost(date: $0.date, content: .video($0.url)) }
    + photoArray.map { TimelinePost(date: $0.date, content: .photo($0.image)) })
    .sorted()

你可能想把它变成一个函数或者在这里更改逻辑......由你决定。

现在timelineArray是按日期顺序排序的结构数组(TimelinePost)。它包含您的所有视频和照片。

您甚至可以添加扩展名以向其提供UICollectionViewCell重用标识符...

extension TimelinePost {
    var reuseIdentifier: String {
        switch content {
        case .photo:
            return "PhotoCell"
        case .video:
            return "VideoCell"
        }
    }
}

要获取cellForItem中的重用标识符(对于您的集合视图),您只需执行类似...

的操作。
let timelinePost = timelineArray[indexPath.item]
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: timelinePost.reuseIdentifier, for: indexPath)