我已经实现了一个自定义的FlowLayout子类,这显然阻止我通过故事板添加headerView(复选框消失了).有没有其他方法可以使用故事板?
关于如何以编程方式添加headerView有一些答案,但它们在Objective-C中,如何使用Swift添加一个?
下面没有产生标题视图,我无法弄清楚为什么?
CollectionViewController { override func viewDidLoad() { super.viewDidLoad() // Setup Header self.collectionView!.registerClass(PinHeaderView.self,forSupplementaryViewOfKind:UICollectionElementKindSectionHeader,withReuseIdentifier: headerIdentifier) } override func collectionView(collectionView: UICollectionView,viewForSupplementaryElementOfKind kind: String,atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView { //1 switch kind { //2 case UICollectionElementKindSectionHeader: //3 let headerView = collectionView.dequeueReusableSupplementaryViewOfKind(kind,withReuseIdentifier: "PinHeaderView",forIndexPath: indexPath) as! PinHeaderView headerView.pinHeaderLabel.text = boardName return headerView default: //4 fatalError("Unexpected element kind") } } } class PinHeaderView: UICollectionReusableView { @IBOutlet weak var pinHeaderLabel: UILabel! }
我的布局类:
import UIKit protocol PinterestLayoutDelegate { // 1. Method to ask the delegate for the height of the image func collectionView(collectionView:UICollectionView,heightForPhotoAtIndexPath indexPath:NSIndexPath,withWidth:CGFloat) -> CGFloat // 2. Method to ask the delegate for the height of the annotation text func collectionView(collectionView: UICollectionView,heightForAnnotationAtIndexPath indexPath: NSIndexPath,withWidth width: CGFloat) -> CGFloat func columnsForDevice() -> Int } class PinterestLayoutAttributes:UICollectionViewLayoutAttributes { // 1. Custom attribute var photoHeight: CGFloat = 0.0 var headerHeight: CGFloat = 0.0 // 2. Override copyWithZone to conform to NSCopying protocol override func copyWithZone(zone: NSZone) -> AnyObject { let copy = super.copyWithZone(zone) as! PinterestLayoutAttributes copy.photoHeight = photoHeight return copy } // 3. Override isEqual override func isEqual(object: AnyObject?) -> Bool { if let attributtes = object as? PinterestLayoutAttributes { if( attributtes.photoHeight == photoHeight ) { return super.isEqual(object) } } return false } } class PinterestLayout: UICollectionViewLayout { //1. Pinterest Layout Delegate var delegate:PinterestLayoutDelegate! //2. Configurable properties //moved numberOfColumns var cellPadding: CGFloat = 6.0 //3. Array to keep a cache of attributes. private var cache = [PinterestLayoutAttributes]() //4. Content height and size private var contentHeight:CGFloat = 0.0 private var contentWidth: CGFloat { let insets = collectionView!.contentInset return CGRectGetWidth(collectionView!.bounds) - (insets.left + insets.right) } override class func layoutAttributesClass() -> AnyClass { return PinterestLayoutAttributes.self } override func prepareLayout() { // 1. Only calculate once //if cache.isEmpty { // 2. Pre-Calculates the X Offset for every column and adds an array to increment the currently max Y Offset for each column let numberOfColumns = delegate.columnsForDevice() let columnWidth = contentWidth / CGFloat(numberOfColumns) var xOffset = [CGFloat]() for column in 0 ..< numberOfColumns { xOffset.append(CGFloat(column) * columnWidth ) } var column = 0 var yOffset = [CGFloat](count: numberOfColumns,repeatedValue: 0) // 3. Iterates through the list of items in the first section for item in 0 ..< collectionView!.numberOfItemsInSection(0) { let indexPath = NSIndexPath(forItem: item,inSection: 0) // 4. Asks the delegate for the height of the picture and the annotation and calculates the cell frame. let width = columnWidth - cellPadding*2 let photoHeight = delegate.collectionView(collectionView!,heightForPhotoAtIndexPath: indexPath,withWidth:width) let annotationHeight = delegate.collectionView(collectionView!,heightForAnnotationAtIndexPath: indexPath,withWidth: width) let height = cellPadding + photoHeight + annotationHeight + cellPadding let frame = CGRect(x: xOffset[column],y: yOffset[column],width: columnWidth,height: height) let insetFrame = CGRectInset(frame,cellPadding,cellPadding) // 5. Creates an UICollectionViewLayoutItem with the frame and add it to the cache let attributes = PinterestLayoutAttributes(forCellWithIndexPath: indexPath) attributes.photoHeight = photoHeight attributes.frame = insetFrame cache.append(attributes) // 6. Updates the collection view content height contentHeight = max(contentHeight,CGRectGetMaxY(frame)) yOffset[column] = yOffset[column] + height column = column >= (numberOfColumns - 1) ? 0 : ++column } //} } override func layoutAttributesForSupplementaryViewOfKind(elementKind: String,atIndexPath indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? { let attributes = PinterestLayoutAttributes(forSupplementaryViewOfKind: elementKind,withIndexPath: indexPath) attributes.headerHeight = 100.0 attributes.frame = (self.collectionView?.frame)! return attributes } override func collectionViewContentSize() -> CGSize { return CGSize(width: contentWidth,height: contentHeight) } override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? { var layoutAttributes = [UICollectionViewLayoutAttributes]() // Loop through the cache and look for items in the rect for attributes in cache { if CGRectIntersectsRect(attributes.frame,rect ) { layoutAttributes.append(attributes) } } return layoutAttributes } }
解决方法
您可以在storyboard中添加标题视图,拖动“Collection Reusable View”并将其放在collectionView中,然后在storyboard中设置其类和标识符.或者,您可以按照代码中所示以编程方式注册自定义标头类.
self.collectionView!.registerClass(PinHeaderView.self,forSupplementaryViewOfKind:UICollectionElementKindSectionHeader,withReuseIdentifier:headerIdentifier)
viewForSupplementaryElementOfKind委托方法不完整,不处理案例UICollectionElementKindSectionFooter,对页眉视图执行与标题视图相同的操作.如果您没有看到它,请将标题视图图层的borderWidth设置为大于0的值,它可能会显示出来.