2015-07-10 56 views
2

使用的Xcode 7.0-β,夫特2.0,IOS 9支撐編輯框高度可重複使用的集查看

我有一個視圖控制器,它包含一個集合視圖。裏面是一個標題:集合可重用視圖,一個集合:集合視圖單元和一個頁腳:集合可重用視圖。

在標題中,我有登錄,註冊或註銷的功能。 根據點擊哪個按鈕,此標題中的視圖將被隱藏或不顯示。現在我要做的最後一件事是重新調整標題視圖的框架高度(集合可重用視圖)。因爲登錄時,RegisterView和LoginView都將被隱藏,這將留下大量的空白空間。

這裏是我的結構的圖像:

structure views

我很快發現我無法的任何約束添加到收藏可重複使用的視圖:(

所有功能頁眉Collection可重用視圖是在類UICollectionReusableView的類中,我能夠讀取self.frame.height,但是我無法寫入它,我似乎可以編輯框架(爲什麼高度只讀,而框架不是,蘋果? ),但這沒有效果,即使是self.frame = CGRectZero沒有做任何事情。

我注意到在初始化頁眉和頁腳(func collectionView, switch on kind -> UICollectionElementKindSectionHeader)時,我可以在主ViewController.swift中執行此操作,但這不是我想要的,因爲它應該在按鈕單擊時發生更改。

現在,我將RegisterView向上移動(我編輯代碼中的頂部約束)。

回答

4

您不能直接操縱集合視圖中視圖的大小。要控制它們的尺寸,您的收藏視圖的代表應該符合UICollectionViewDelegateFlowLayout,那麼您可以通過在該協議上實現方法collectionView(_:layout:referenceSizeForHeaderInSection:)來返回該部分中標題的任意大小。如果標題不可見,只需返回0.0高度。一旦以某種方式更改了視圖控制器的狀態,並需要更新此佈局,請在集合視圖的佈局上調用invalidateLayout()以在要調用的委託上觸發這些佈局方法。

class MyCollectionViewController : UICollectionViewController, UICollectionViewDelegateFlowLayout { 

    var shouldHideHeader: Bool = false { 
     didSet { 
      self.collectionView?.collectionViewLayout.invalidateLayout() 
     } 
    } 

    let defaultHeaderSize: CGFloat = 100.0 
    let loginHeaderSectionIndex: Int = 0 

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

     if self.shouldHideHeader && section == self.loginHeaderSectionIndex { 
      return CGSize(width: collectionView.bounds.width, height: 0.0) 
     } 
     else { 
      return CGSize(width: collectionView.bounds.width, height: self.defaultHeaderSize) 
     } 
    } 
} 
+0

由於我在頭文件類中具有所有功能,訪問shouldHideHeader var或其他任何方法的最佳方法是什麼? – CularBytes

-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) 
     } 
    } 
}