Ant*_*ine 15 ios uicollectionview uicollectionviewlayout swift tvos
我正在尝试创建一个粘性补充标题,它始终保持在顶部并且不会响应滚动事件.到目前为止我找到的解决方案仍然对bounch滚动做出反应,并使用自定义flowlayout进行修复,这可能也是我的问题的解决方案.
我想这样做的原因是标题在其他地方使用,应该是可重用的.我希望这可以通过这种方式解决,我不必创建一个单独的视图.
正如我在Swift中所做的那样,在Swift中有一个例子会很棒.
Dar*_*ari 65
最简单的iOS 9 +解决方案,因为它不需要编写UICollectionViewFlowLayout的子类.
在带有collectionView的viewController的viewDidLoad中使用以下代码:
let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout // casting is required because UICollectionViewLayout doesn't offer header pin. Its feature of UICollectionViewFlowLayout
layout?.sectionHeadersPinToVisibleBounds = true
Run Code Online (Sandbox Code Playgroud)
它也被@Antoine暗示.
我找到的最终解决方案:
使用此自定义流布局,可以修复此粘性标头:
class StickyHeaderCollectionViewFlowLayout: UICollectionViewFlowLayout {
override func layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]? {
var superAttributes: [UICollectionViewLayoutAttributes]? = super.layoutAttributesForElementsInRect(rect) as? [UICollectionViewLayoutAttributes]
if superAttributes == nil {
// If superAttributes couldn't cast, return
return super.layoutAttributesForElementsInRect(rect)
}
let contentOffset = collectionView!.contentOffset
var missingSections = NSMutableIndexSet()
for layoutAttributes in superAttributes! {
if (layoutAttributes.representedElementCategory == .Cell) {
if let indexPath = layoutAttributes.indexPath {
missingSections.addIndex(layoutAttributes.indexPath.section)
}
}
}
for layoutAttributes in superAttributes! {
if let representedElementKind = layoutAttributes.representedElementKind {
if representedElementKind == UICollectionElementKindSectionHeader {
if let indexPath = layoutAttributes.indexPath {
missingSections.removeIndex(indexPath.section)
}
}
}
}
missingSections.enumerateIndexesUsingBlock { idx, stop in
let indexPath = NSIndexPath(forItem: 0, inSection: idx)
if let layoutAttributes = self.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionHeader, atIndexPath: indexPath) {
superAttributes!.append(layoutAttributes)
}
}
for layoutAttributes in superAttributes! {
if let representedElementKind = layoutAttributes.representedElementKind {
if representedElementKind == UICollectionElementKindSectionHeader {
let section = layoutAttributes.indexPath!.section
let numberOfItemsInSection = collectionView!.numberOfItemsInSection(section)
let firstCellIndexPath = NSIndexPath(forItem: 0, inSection: section)!
let lastCellIndexPath = NSIndexPath(forItem: max(0, (numberOfItemsInSection - 1)), inSection: section)!
let (firstCellAttributes: UICollectionViewLayoutAttributes, lastCellAttributes: UICollectionViewLayoutAttributes) = {
if (self.collectionView!.numberOfItemsInSection(section) > 0) {
return (
self.layoutAttributesForItemAtIndexPath(firstCellIndexPath),
self.layoutAttributesForItemAtIndexPath(lastCellIndexPath))
} else {
return (
self.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionHeader, atIndexPath: firstCellIndexPath),
self.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionFooter, atIndexPath: lastCellIndexPath))
}
}()
let headerHeight = CGRectGetHeight(layoutAttributes.frame)
var origin = layoutAttributes.frame.origin
origin.y = min(contentOffset.y, (CGRectGetMaxY(lastCellAttributes.frame) - headerHeight))
// Uncomment this line for normal behaviour:
// origin.y = min(max(contentOffset.y, (CGRectGetMinY(firstCellAttributes.frame) - headerHeight)), (CGRectGetMaxY(lastCellAttributes.frame) - headerHeight))
layoutAttributes.zIndex = 1024
layoutAttributes.frame = CGRect(origin: origin, size: layoutAttributes.frame.size)
}
}
}
return superAttributes
}
override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool {
return true
}
}
Run Code Online (Sandbox Code Playgroud)
要像传统一样创建标题粘贴的布局,请更改以下行:
origin.y = min(contentOffset.y, (CGRectGetMaxY(lastCellAttrs.frame) - headerHeight))
Run Code Online (Sandbox Code Playgroud)
到这一行:
origin.y = min(max(contentOffset.y, (CGRectGetMinY(firstCellAttrs.frame) - headerHeight)), (CGRectGetMaxY(lastCellAttrs.frame) - headerHeight))
Run Code Online (Sandbox Code Playgroud)
希望这对其他人有用!
更新
更新以修复崩溃(感谢Robert Atkins!)和Swift 1.2的一些更新
tvOS和iOS 9
tvOS和iOS 9引入了sectionHeadersPinToVisibleBounds可以使用的属性
| 归档时间: |
|
| 查看次数: |
25010 次 |
| 最近记录: |