将数据从 Collectionview 传递到 UIcollectionResuableview

Posted

技术标签:

【中文标题】将数据从 Collectionview 传递到 UIcollectionResuableview【英文标题】:pass data from Collectionview to UIcollectionResuableview 【发布时间】:2017-11-16 13:30:15 【问题描述】:

我有一个collectionView,数据(字符串)在加载时从另一个VC 传递到它。现在,当我想将此数据(字符串)传递给 UICollectionReusabelView 时。我正在执行以下步骤

CollectionViewVC:

class PhotoDetailVC: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, PDHeaderViewDelegate 



// Following variables are the ones to which the data is passed to. 
var image : String!
var user: User!
var post: Posts!


@IBOutlet weak var collectionView: UICollectionView!


override func viewDidLoad() 
    super.viewDidLoad()

    print(post.imageURL)

    collectionView.delegate = self
    collectionView.dataSource = self

    setupCells()
    increaseView()



func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView 
    let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "mainImage", for: indexPath) as! PDHeader

    // I am setting the ReusableView properties through this section. Instead I just want to pass them to the header and then do stuff over there.

    header.post = self.post
    header.lol = post.postauthor
    header.label.text = post.caption
    header.label.sizeToFit()
    header.delegate = self
    let ref = URL(string: post.imageURL)
    Nuke.loadImage(with: ref!, into: header.mainPic)
    imageInHeaderForAuthor(author: post.postauthor, view: header.profilePic)

    return header


func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize 

    let size = CGSize(width: collectionView.frame.width, height: collectionView.frame.height - 15)
    return size



func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 

    let width = (collectionView.bounds.size.width/3) - 1
    let size = CGSize(width: width, height: width)
    return size



func collectionView(_ collectionView: UICollectionView,
                    layout collectionViewLayout: UICollectionViewLayout,
                    minimumInteritemSpacingForSectionAt section: Int) -> CGFloat 
    return 1.0


func collectionView(_ collectionView: UICollectionView, layout
    collectionViewLayout: UICollectionViewLayout,
                    minimumLineSpacingForSectionAt section: Int) -> CGFloat 
    return 1.0



func imageInHeaderForAuthor(author: String, view: UIImageView)
    FBDataservice.ds.REF_USERS.child(author).observeSingleEvent(of: .value, with:  (snapshot) in
        if let allData = snapshot.value as? Dictionary<String, Any> 
            if let cred = allData["credentials"] as? Dictionary<String, Any> 
                let postuser = User(userid: author, userData: cred)
                if postuser.userPic != nil 
                    let req = URL(string: postuser.userPic)
                    Nuke.loadImage(with: req!, into: view)
                
            
        
    )



可重用视图:

class PDHeader: UICollectionReusableView, FloatyDelegate 

@IBOutlet weak var label: UILabel!
@IBOutlet weak var mainPic: UIImageView!
@IBOutlet weak var profilePic: UIImageView!

var image : String!
var post: Posts!
var lol: String!
var floaty = Floaty()
var isOwner : Bool!
var delegate: PDHeaderViewDelegate!



override func awakeFromNib() 
    super.awakeFromNib()

    //This returns nil every time.
    print(post.postauthor)

    layoutFAB()
    profilePic.makeCircle()
    label.addDropShadow(opacity: 3, radius: 8)






func setDelegate(delegate: PDHeaderViewDelegate) 
    self.delegate = delegate


func layoutFAB() 
    floaty.openAnimationType = .pop
    floaty.buttonImage = UIImage(named: "options")
    floaty.addItem("Report", icon: UIImage(named: "trash"))  item in
        self.delegate.fabReportClicked()
    
    if isOwner
        floaty.addItem("Edit Profile", icon: UIImage(named: "edit"))  item in
            self.delegate.fabEditClicked()
        
        floaty.addItem("Delete", icon: UIImage(named: "trash"))  item in
            self.delegate.fabDeleteButton()
        
    

    floaty.fabDelegate = self
    floaty.buttonColor = UIColor.white
    floaty.hasShadow = true
    floaty.size = 45
    addSubview(floaty)



我已经用问题评论了代码。 TL;DR - 集合不会将数据传递给标题,因此我必须从viewForSupplementaryElementOfKind 设置它们。

这里的实际问题是什么?在数据传递给它之前是否正在加载标题?如果没有,我该如何解决这个问题?

【问题讨论】:

1) awakefromNib 中的发布数据将始终为零,因为尚未设置变量。 2)存在歧义header.post = self.post header.post = post.postauthor。你设置了两次变量..它可能导致 post.postauthour 是 nil 编辑了我的问题。粘贴代码时出错 你没有提到实际问题是什么?图片没有加载吗? 问题是awakeForNib() 在你设置collectionView:viewForSupplementaryElementOfKind:at: 中的所有这些值之前被调用,所以所有的布局逻辑都是用错误的数据完成的。 是的,我最后提到了。图像没有传递,字符串也没有传递。我必须从委托方法设置它,可以在内部设置它。它总是返回 nil 【参考方案1】:

如果我理解你可以试试这个选项:

class PDHeader: UICollectionReusableView, FloatyDelegate 

    @IBOutlet weak var label: UILabel!
    @IBOutlet weak var mainPic: UIImageView!
    @IBOutlet weak var profilePic: UIImageView!

    var image : String!
    var lol: String!
    var floaty = Floaty()
    var isOwner : Bool!
    var delegate: PDHeaderViewDelegate!

    var post: Posts!
        didSet 
           lol = post.postauthor
           label.text = post.caption
           // etc ...
        

然后:

func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView 
    let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "mainImage", for: indexPath) as! PDHeader

    header.post = self.post
    header.delegate = self

    return header

【讨论】:

您好,感谢您的帮助。这个解决方案工作得很好,但是一旦我尝试访问lol 范围之外的lol,它就会返回nil 您好,如果您需要在 post didSet 之外使用您的 lol 值,例如在函数中,您可以这样做并在 lol didSet 中调用它。你得到 nil 是因为你在调用它的那一刻没有设置值。但是,如果您想在 ViewController 中重用您的标头变量,则在设置标头帖子后,您可以检索所有值。 太棒了!那是我的工作! @captain_haddock 是的,当然。您需要为标头设置委托,并使您的视图控制器符合它。 @captain_haddock 我明白你的意思了,这个例子中的标题是自定义的,这就是为什么它有一个委托属性。在不检查您的代码的情况下,我能想到的最简单的解决方案是您可以在视图控制器中处理您需要的操作。无论如何,如果你愿意,你可以给我一个链接到你的项目,并解释你所面临的问题:)

以上是关于将数据从 Collectionview 传递到 UIcollectionResuableview的主要内容,如果未能解决你的问题,请参考以下文章

将 collectionview 从函数传递到 Selector (UILongPressGestureRecognizer)

如何将数据从集合视图传递到表视图类?

如何将值从 tableview 传递到 collectionview

Swift 4:将数据从集合视图单元传递到另一个没有故事板的视图控制器

如何在 iOS 中更新 collectionView?

Xamarin.Forms 如何将数据从 CollectionView 传输到不同的视图?