ios – UICollectionViewFlowLayout将节标题放在Section Left Inset上

我试图修改UICollectionViewFlowLayout(垂直滚动),以便将每个节标题放在该节的所有项目的左侧(而不是在顶部,这是默认值).

也就是说,这是默认行为:

《ios – UICollectionViewFlowLayout将节标题放在Section Left Inset上》

……这就是我想要的:

《ios – UICollectionViewFlowLayout将节标题放在Section Left Inset上》

所以我将UICollectionViewFlowLayout子类化:

override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    guard let attributesToReturn = super.layoutAttributesForElementsInRect(rect) else {
        return nil
    }

    // Copy to avoid the dreadded "Cached frame mismatch" runtime warning:
    var copiedAttributes = [UICollectionViewLayoutAttributes]()

    for attribute in attributesToReturn {
        copiedAttributes.append(attribute.copy() as! UICollectionViewLayoutAttributes)
    }

    for attributes in copiedAttributes {
        if let kind = attributes.representedElementKind {
            // Non nil: It is a supplementary View

            if kind == UICollectionElementKindSectionHeader {
                // HEADER

                var frame = attributes.frame
                frame.origin.y = frame.origin.y + frame.size.height
                frame.size.width = sectionInset.left
                attributes.frame = frame     
            }
        }
        else{
            // Nil: It is an item
        }
    }
    return copiedAttributes
}

另外,为了好的衡量(?),我采用了协议UICollectionViewDelegateFlowLayout并实现了这个方法(虽然不清楚什么是优先的.然后,故事板文件中有设置,但那些似乎被运行时对应物覆盖):

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

    let left = (collectionViewLayout as! UICollectionViewFlowLayout).sectionInset.left

    return CGSizeMake(left, 1)
}

…并且我成功地将标题降低到其部分的第一行;但是,标头最初占用的空间保持打开状态:

《ios – UICollectionViewFlowLayout将节标题放在Section Left Inset上》

…我唯一可以做到的方法是将标题视图高度设置为1,将“剪辑子视图”设置为false,以便显示标签(如果我将高度设置为0,则不绘制标签),但这绝对不是最优雅的解决方案(并且可能会在-say-iOS 9.2中破解)

也就是说,标题的实际高度链接到各部分之间的垂直空间:我不能将空间设置为零,同时将标题视图保持在合理的大小以便显示.

也许我也应该将所有部分项目向上移动(与我的标题高度相同),以填补空洞?

最佳答案

- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSArray *originalAttributes = [super layoutAttributesForElementsInRect:rect];
    NSMutableArray *allAttributes = [NSMutableArray new];
    for (UICollectionViewLayoutAttributes* attributes in originalAttributes) {
        [allAttributes addObject:[attributes copy]];
    }

    for (UICollectionViewLayoutAttributes *attributes in allAttributes) {
         NSString *kind = attributes.representedElementKind;
         if (kind == UICollectionElementKindSectionHeader) {
            CGRect frame = attributes.frame;
            UICollectionViewLayoutAttributes *cellAttrs = [super layoutAttributesForItemAtIndexPath:attributes.indexPath];
            frame.origin.x = frame.origin.x;
            frame.size.height = self.sectionInset.top;
            frame.size.width = cellAttrs.frame.size.width;
            attributes.frame = frame;
         }
    }

    return allAttributes;
}
点赞