编辑框架高度集合可重用视图

时间:2015-07-10 17:20:37

标签: ios xcode swift swift2 uicollectionreusableview

使用Xcode 7.0 beta,Swift 2.0,支持IOS 9

我有一个View Controller,它包含一个Collection View。里面是标题:集合可重用视图,集合:集合查看单元格和页脚:集合可重用视图。

在标题内,我有登录,注册或注销的功能。 根据单击的按钮,此标题内的视图将被隐藏或不隐藏。现在我要做的最后一件事是重新调整标题视图的框架高度(Collection Reusable View)。因为登录时,RegisterView和LoginView都将被隐藏,这将留下大量的空白空间。

这是我的结构图像:

structure views

我很快注意到我无法向Collection Reusable View添加任何约束:(

标题Collection Reusable View的所有功能都在扩展UICollectionReusableView的类中。我能够阅读self.frame.height,但我无法写信。我似乎能够编辑框架(为什么高度是只读的,而框架不是,苹果?)。然而,即使self.frame = CGRectZero没有做任何事情,这也没有效果。

我注意到在初始化页眉和页脚(func collectionView, switch on kind -> UICollectionElementKindSectionHeader)时我可以在主ViewController.swift中执行此操作,但这不是我想要的,因为它应该在按钮点击时更改。

现在,我向上移动RegisterView(我编辑代码中的顶部约束)。

2 个答案:

答案 0 :(得分:4)

您无法直接操纵集合视图中视图的大小。要控制它们的大小,集合视图的委托应符合<source-file src="libs/mylib.jar" target-dir="libs" />,然后通过在该协议上实现方法UICollectionViewDelegateFlowLayout,您可以返回该节中标题的任何大小。如果标题不可见,只需返回collectionView(_:layout:referenceSizeForHeaderInSection:)的高度即可。一旦您以一种需要更新此布局的方式更改了视图控制器的状态,请在集合视图的布局上调用0.0以触发要调用的委托上的这些布局方法。

invalidateLayout()

答案 1 :(得分:-1)

帕特里克给出了更改标题高度的正确答案,但是,正如我在我的问题中所说,我的标题功能在不同的类中,所以我真的不知道如何访问真正的viewController类。

如果你保持简单,你可以创建一个从故事板到该类的动作链接,我还有一些操作要做,而不仅仅是响应按钮点击。这就是我所做的:

class MyViewController : UIViewController, UICollectionDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout{  

    var headerHeight: CGFloat = 100.0
    var shouldChangeHeader : Bool? = false
    let loginHeaderSectionIndex: Int = 0

   func setHeaderHeight(height : CGFloat!)
   {
       headerHeight = height
       shouldChangeHeader = true
       self.collectionView.collectionViewLayout.invalidateLayout()
   }

    func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
        switch kind
        {
        case UICollectionElementKindSectionHeader:
            let headerView = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: "loginHeader", forIndexPath: indexPath) as! LoginHeaderView
           //you should already have this method, LoginHeaderView is the class with all the functionality for the header, we register a callback.
            headerView.registerHeightChangeCallback(setHeaderHeight)
            return headerView
       }
}
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
        //here we actually change the height, best is to include a if-condition, so it won't change on loading unless you especially call it.
        if self.shouldChangeHeader && self.loginHeaderSectionIndex == section {
            shouldChangeHeader = false
            return CGSize(width: collectionView.bounds.width, height: headerHeight )
        }
        else {
            //do nothing, keep as it is now.
            return CGSize(width: collectionView.bounds.width, height: collectionView.bounds.height) /
        }
    }
}

class LoginHeaderView : UICollectionReusableView {

    var heightCallback : ((height : CGFloat!)-> Void)?
    func registerHeightChangeCallback(callback :((height : CGFloat!)-> Void)?)
    {
        heightCallback = callback
    }
    @IBAction func buttonClicked( sender: AnyObject? ) { //or from any other method...

        if(heightCallback != nil)
        {
            heightCallback!(height: 200)
        }
    }
}