UICollectionViewCell使用原型大小

时间:2014-03-17 23:00:08

标签: ios objective-c uicollectionview uicollectionviewcell

我有一个带有三个不同原型单元的UICollectionView,每个原型单元通过Storyboard设置不同的高度。在运行时,Collection View使用自己的单元格大小,忽略我的Storyboard。

我目前正在使用collectionView:layout:sizeForItemAtIndexPath:使用几个条件来直接设置每个CGSize。

有没有更好的方法来设置单元格大小?我似乎无法检索每个单元格的Storyboard大小,而且CGSizeMake似乎太硬编码而且不够灵活。

3 个答案:

答案 0 :(得分:2)

目前似乎没有简单的方法:

  • 从故事板中获取UICollectionViewCell原型单元大小运行时。
  • 只在一个地方管理原型单元的大小(而不必在Storyboard单元原型中输入它们并实现sizeForItemAtIndexPath)。

建议的方法here(对于UITableViews)不起作用,因为在dequeueReusableCellWithReuseIdentifier中使用sizeForItemAtIndexPath会导致无限循环。

但是,我已设法通过以下方式执行此操作

  1. 在所有故事板中的每个UICollectionViewCell原型单元格中添加唯一的(在每个故事板中的所有UICollectionView)重用标识符。

  2. 使用从所有故事板中提取Run script帧大小的脚本,为您的项目添加UICollectionViewCell构建阶段。

    output=${PROJECT_DIR}/StoryboardPrototypeCellSizes.h
    printf "@{" > $output
    
    for storyboard in $(find ${PROJECT_DIR} -name "*.storyboard")
    do
        echo "Scanning storyboard $storyboard..."
        delimiter=
        for line in $(xpath $storyboard "//collectionViewCell/@reuseIdentifier[string-length()>0] | //collectionViewCell/rect" 2>&-)
        do
            case $line in
                reuseIdentifier*)
                    reuseIdentifier=$(sed 's/[^"]*"\([^"]*\)".*/\1/' <<< $line)
                    ;;
                width*)
                    if [ -n "$reuseIdentifier" ]; then
                        width=$(sed 's/[^"]*"\([^"]*\)".*/\1/' <<< $line)
                    fi
                    ;;
                height*)
                    if [ -n "$reuseIdentifier" ]; then
                        height=$(sed 's/[^"]*"\([^"]*\)".*/\1/' <<< $line)
                    fi
                    ;;
            esac
    
            if [ -n "$reuseIdentifier" ] && [ -n "$width" ] && [ -n "$height" ]; then
                printf "$delimiter@\"$reuseIdentifier\" : [NSValue valueWithCGSize:CGSizeMake($width, $height)]" >> $output
                unset reuseIdentifier
                unset width
                unset height
                delimiter=,\\n
            fi
        done
    done
    
    printf "};\n" >> $output
    

    这将创建一个名为StoryboardPrototypeCellSizes.h的头文件,其中包含以下示例内容:

    @{@"TodayCell" : [NSValue valueWithCGSize:CGSizeMake(320, 80)],
    @"SpecialDayCell" : [NSValue valueWithCGSize:CGSizeMake(320, 42)],
    @"NameDayCell" : [NSValue valueWithCGSize:CGSizeMake(320, 30)]};
    
  3. 添加帮助方法,在控制UICollectionViewCell的视图控制器中返回UICollectionView重用标识符:

    - (NSString *)cellReuseIdentifierAtIndexPath:(NSIndexPath *)indexPath
    {
        switch (indexPath.item) {
            case 0: return @"TodayCell";
            case 1: return @"SpecialDayCell";
            case 2: return @"NameDayCell";
        }
        return nil;
    }
    
  4. 请务必在cellForItemAtIndexPath中使用相同的重用标识符:

    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    {
        UICollectionViewCell *cell =
            [collectionView dequeueReusableCellWithReuseIdentifier:
                [self cellReuseIdentifierAtIndexPath:indexPath]
                forIndexPath:indexPath];
        ...
    
  5. 最后实施sizeForItemAtIndexPath

    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
    {
        NSDictionary *storyboardPrototypeCellSizes =
    #import "StoryboardPrototypeCellSizes.h"
    
         return [(NSValue *)storyboardPrototypeCellSizes[
                 [self cellReuseIdentifierAtIndexPath:indexPath]
                ] CGSizeValue];
    }
    
  6. 此解决方案允许您在故事板中仅定义UICollectionViewCell原型单元格大小一次,并且在运行时也不会执行任何非App-Store兼容。

    ****编辑:****您还可以通过添加具有相同内容的另一个脚本并将“collectionViewCell”替换为“collectionReusableView”来获取UICollectionReusableView大小,并将头文件重命名为,例如,StoryboardReusableViewSizes.h

答案 1 :(得分:0)

没有更好的方法来设置单元格大小。单元格大小在UICollectionView中的几个位置使用 - 用于定位,用于滚动指示器。如果用户使用数千个小单元滚动集合,则尽可能快地接收它们非常非常重要。因此创建单元格并询问它的大小不是一个选项。你必须实现collectionView:layout:sizeForItemAtIndexPath:它应该可以快速工作。

答案 2 :(得分:-1)

您是否在UICollectionView中使用了流量布局?如果是,您可以使用sizeForItemAtIndexPath协议的UICollectionViewDelegateFlowLayout方法来提供单元格的大小。如果您在应用中使用OSS组件时遇到问题,可以使用RFQuiltLayout来实现此目的。