使用Xcode 7.0 beta,Swift 2.0,支持IOS 9
我有一个View Controller,它包含一个Collection View。里面是标题:集合可重用视图,集合:集合查看单元格和页脚:集合可重用视图。
在标题内,我有登录,注册或注销的功能。 根据单击的按钮,此标题内的视图将被隐藏或不隐藏。现在我要做的最后一件事是重新调整标题视图的框架高度(Collection Reusable View)。因为登录时,RegisterView和LoginView都将被隐藏,这将留下大量的空白空间。
这是我的结构图像:
我很快注意到我无法向Collection Reusable View添加任何约束:(
标题Collection Reusable View的所有功能都在扩展UICollectionReusableView
的类中。我能够阅读self.frame.height
,但我无法写信。我似乎能够编辑框架(为什么高度是只读的,而框架不是,苹果?)。然而,即使self.frame = CGRectZero
没有做任何事情,这也没有效果。
我注意到在初始化页眉和页脚(func collectionView, switch on kind -> UICollectionElementKindSectionHeader
)时我可以在主ViewController.swift中执行此操作,但这不是我想要的,因为它应该在按钮点击时更改。
现在,我向上移动RegisterView(我编辑代码中的顶部约束)。
答案 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)
}
}
}