【问题标题】:iOS UICollectionView header & footer locationiOS UICollectionView 页眉和页脚位置
【发布时间】:2014-05-16 06:15:18
【问题描述】:

iOS 7 中工作,如何在UICollectionView 中指定页眉和页脚框的位置?

我有一个自定义的UICollectionViewFlowLayout。我已经覆盖了

-(void)prepareLayout

-(NSArray*) layoutAttributesForElementsInRect:(CGRect)rect

-(UICollectionViewLayoutAttributes*) layoutAttributesForSupplementaryViewOfKind: (NSString*)kind atIndexPath:(NSIndexPath*)indexPath

我的问题是,我不确定如何指定标题位置。我已经指定了prepareLayout中存在一个header:

-(void)prepareLayout
{
[super prepareLayout];

boundsSize = self.collectionView.bounds.size;
midX = boundsSize.width / 2.0f;
curIndex = 0;

self.headerReferenceSize = CGSizeMake(CELL_SIZE, TITLE_HEIGHT);
self.footerReferenceSize = CGSizeMake(0, 0);

self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
self.sectionInset = UIEdgeInsetsMake(TOP_INSET, LEFT_INSET, BOTTOM_INSET, RIGHT_INSET);
self.minimumLineSpacing = LINE_SPACING;
self.minimumInteritemSpacing = INTERIM_SPACING;
self.itemSize = CGSizeMake(CELL_SIZE, CELL_SIZE);

}

我只是不知道要设置的自定义 FlowLayout 的正确属性,因为似乎没有像“HeaderLocation”这样的东西可以设置为 LayoutAttributes 或布局对象本身。现在,当我希望它们出现在每个图像上方(水平滚动)时,它出现在我的图像的侧面/之间。

我尝试了以下方法:

-(UICollectionReusableView*) collectionView: (UICollectionView*)collectionView viewForSupplementaryElementOfKind:(NSString*)kind atIndexPath:(NSIndexPath*)indexPath
{
    NSLog(@"**ViewForSupplementaryElementOfKind called***");

    CGFloat centerX = collectionView.center.x;
    CGFloat centerY = collectionView.center.y;
    CGFloat titleWidth = [MyLayout titleWidth];
    CGFloat titleHeight = [MyLayout titleHeight];

    MyTitleView* titleView = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:ImageTitleIdentifier forIndexPath:indexPath];

    titleView.frame = CGRectMake(centerX - titleWidth/2.0,
                                 0.0,
                                 titleWidth,
                                 titleHeight);

    return titleView;
}

这不起作用。标题出现在上面与一堆其他标题重叠,然后当我开始滚动(水平)时,它们会跳回错误的位置,在图像之间水平而不是在上面。

PS> 请不要提出任何与 NIB 或 XIB 放置有关的建议。我使用的是 UICollectionView,而不是 UICollectionViewController,所以我实际上没有原型单元可以使用。布局完全以编程方式完成——仅从代码开始——所以我不能简单地打开 XIB 文件并调整文本框的位置。

【问题讨论】:

    标签: ios objective-c uicollectionview flowlayout


    【解决方案1】:

    修改-layoutAttributesForElementsInRect返回的属性是正确的做法,但是如果你想改变屏幕外页眉和页脚的位置,你可能需要自己获取补充视图属性。

    例如,在您的 UICollectionViewFlowLayout 子类中:

    - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
    {
        NSMutableArray *attributesArray = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
    
        // the call to super only returns attributes for headers that are in the bounds,
        // so locate attributes for out of bounds headers and include them in the array
        NSMutableIndexSet *omittedSections = [NSMutableIndexSet indexSet];
        for (UICollectionViewLayoutAttributes *attributes in attributesArray) {
            if (attributes.representedElementCategory == UICollectionElementCategoryCell) {
                [omittedSections addIndex:attributes.indexPath.section];
            }
        }
        for (UICollectionViewLayoutAttributes *attributes in attributesArray) {
            if ([attributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) {
                [omittedSections removeIndex:attributes.indexPath.section];
            }
        }
        [omittedSections enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
            NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:idx];
            UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader
                                                                                                atIndexPath:indexPath];
            [attributesArray addObject:attributes];
        }];
    
        for (UICollectionViewLayoutAttributes *attributes in attributesArray) {
            if ([attributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) {
    
                // adjust any aspect of each header's attributes here, including frame or zIndex
    
            }
        }
    
        return attributesArray;
    }
    

    【讨论】:

    • 感谢您发布这么多代码,但您能否指定您正在编辑的属性是什么?这是最重要的部分。你写道,'//在这里调整每个标题属性的任何方面,包括框架或 zIndex',但是在那里编辑框架会改变标题的放置位置吗?它只是与已经存在的任何内容重叠吗?具体属性是什么? (有很多,我在文档中没有看到名为“headerLocation”或“headerOrigin”或“headerFrame”之类的名称)
    • "...在那里编辑框架会改变标题的放置位置吗?它是否只是与已经存在的任何内容重叠?"但这正是 UICollectionViewLayoutAttribute 的 frame 和 zIndex 属性所做的。我可以温和地建议您先阅读the docs吗?
    • 您可能还会发现this article 有助于更深入地了解 UICollectionViewLayoutAttributes 及其工作原理。
    • 谢谢,关注本。当然,我已经阅读了文档;他们说“例如,页眉和页脚视图的布局与单元格不同,可以为单个部分或整个集合视图提供。”但他们从未说过如何更改这些页眉和页脚的“位置”。我和以前有同样的问题:管理他们位置的财产的名称是什么?在得到答案之前,其他一切都不重要。
    • 集合视图不是这样工作的。您不直接设置页眉或页脚的位置;而是在布局返回的相关 UICollectionViewLayoutAttributes 实例上设置中心或框架属性。 zIndex 确定它是浮动在其余内容之上还是后面。
    【解决方案2】:

    CollectionView Header 高度设置在 Collectionview 委托下方

    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
    

    并在下面的委托中的 Collectionview 标题中设置视图

    - (UICollectionReusableView*)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
    {
        UICollectionReusableView * view = nil;
    
        if ([kind isEqualToString:UICollectionElementKindSectionHeader])
        {
            ColorSectionHeaderView *header = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader
                                                                                withReuseIdentifier:NSStringFromClass([ColorSectionHeaderView class])
                                                                                       forIndexPath:indexPath];
            header.sectionIndex = indexPath.section;
            header.hideDelete = collectionView.numberOfSections == 1; // hide when only one section
            header.delegate = self;
            view = header;
        }
    
    return view;
    

    }

    ViewDidLoad 中的 Ragistred 类

    -(void)ViewDidLoad
    {
    
    [collectionView registerNib:[UINib nibWithNibName:NSStringFromClass([ColorSectionFooterView class]) bundle:nil]
         forSupplementaryViewOfKind:UICollectionElementKindSectionFooter
                withReuseIdentifier:NSStringFromClass([ColorSectionFooterView class])];
    
       [Super ViewDidLoad];
    }
    

    【讨论】:

    • 谢谢,但我已经知道如何更改高度,我想知道在哪里更改位置。如,我想告诉程序将我的标题视图放在内容之上,在 y 坐标 = 0 处。在您的解决方案中,您明确告诉标题放置在某个位置? dequeueReusableSupplementaryView 不能让我控制它。
    • 什么是“MyTitleView”?是类吗?
    • 是的,这是我的头类。
    • 你 ragitsred viewDidLoad 中的类如上我编辑的'
    • Kirit Modi,感谢您的回答,但就像我说的,您没有回答如何更改位置。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-29
    • 1970-01-01
    • 2017-09-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多