UICollectionView标头兼容视图

时间:2013-06-14 04:30:25

标签: ios storyboard uicollectionview uicollectionreusableview

我在故事板中构建了一个UICollectionView,并在视图控制器中实现了所有必需的数据源和委托方法。在故事板中,我检查了集合视图上的Section Header属性,并将标题视图的类设置为UICollectionResusableView的子类(在故事板中)。

从这里开始,我通过故事板将两个UI元素拖到标题视图中 - 标签和分段控件:

enter image description here

执行程序时,标签出现在集合视图的标题视图中(不需要实际代码),但分段控件不会。但是,当分段控件拖到典型的UIView上时,它会显示并且可以操作而不需要代码。即使通过IBOutlet中的代码进行实例化,分段控件也不会出现。

为什么分段控件在集合视图的标题中不可见,而它是典型的UIView,为什么标签显示没有问题?

更新

以下是自定义标题视图的init方法,其中我尝试以编程方式添加分段控件(而不是在故事板中):

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        _segmentedControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:@"One", @"Two", nil]];
        [_segmentedControl setFrame:CGRectMake(0, 0, 100, 50)];
        [_segmentedControl addTarget:self action:@selector(segmentedControlChanged:) forControlEvents:UIControlEventValueChanged];
        [self addSubview:_segmentedControl];
    }
    return self;
}

根据要求,这是主视图控制器中的-[UICollectionReusableView viewForSupplementaryElementOfKind:]方法:

- (UICollectionReusableView *)collectionView:(UICollectionView *)cv viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
    GalleryHeader *headerView = [cv dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView" forIndexPath:indexPath];
    return headerView;
}

1 个答案:

答案 0 :(得分:4)

我无法重现你的故事板问题,当我通过直接在故事板中拖动它来添加分段控件(不需要代码)时,它对我来说很好。至于以编程方式添加它的替代方法,这里的问题是当从故事板初始化视图时(在这种情况下),使用initWithCoder初始化方法(而不是initWithFrame初始化方法)。因此,如果您重写该方法,在那里插入代码,它应该工作:

-(id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if(self){
        _segmentedControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:@"One", @"Two", nil]];
        _segmentedControl.bounds = CGRectMake(0, 0, 100, 50);
        [_segmentedControl addTarget:self action:@selector(segmentedControlChanged:) forControlEvents:UIControlEventValueChanged];
        [self addSubview:_segmentedControl];
    }
    return self;
}

P.S。它不会影响这种特定情况,但您应该这样做:

GalleryHeader *headerView = [cv dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"HeaderView" forIndexPath:indexPath];

而不是:

GalleryHeader *headerView = [cv dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView" forIndexPath:indexPath];

由于要求提供正确视图的集合视图,您应该担心指定它!

编辑:我从故事板创建标题的步骤是:

  • 选择集合视图并勾选标有 Section Header
  • 的框

  • 选择新创建的标题,然后在标识检查器中选择正确的类

enter image description here

  • 为标题部分添加唯一标识符

enter image description here

  • 拖动故事板中标题中的UI元素(我也更改了其背景颜色)

enter image description here

  • 最后在集合视图的数据源类
  • 中实现collectionView:viewForSupplementaryElementOfKind:atIndexPath:方法
 -(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView
          viewForSupplementaryElementOfKind:(NSString *)kind 
                                atIndexPath:(NSIndexPath *)indexPath
 {
     return [self.collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"collectionViewHeader" forIndexPath:indexPath];
 }

如果你能发现你做了什么和我做了什么之间的任何区别,请告诉我。