我有一个带有三个不同原型单元的UICollectionView,每个原型单元通过Storyboard设置不同的高度。在运行时,Collection View使用自己的单元格大小,忽略我的Storyboard。
我目前正在使用collectionView:layout:sizeForItemAtIndexPath:使用几个条件来直接设置每个CGSize。
有没有更好的方法来设置单元格大小?我似乎无法检索每个单元格的Storyboard大小,而且CGSizeMake似乎太硬编码而且不够灵活。
答案 0 :(得分:2)
目前似乎没有简单的方法:
sizeForItemAtIndexPath
)。建议的方法here(对于UITableViews)不起作用,因为在dequeueReusableCellWithReuseIdentifier
中使用sizeForItemAtIndexPath
会导致无限循环。
但是,我已设法通过以下方式执行此操作:
在所有故事板中的每个UICollectionViewCell
原型单元格中添加唯一的(在每个故事板中的所有UICollectionView
)重用标识符。
使用从所有故事板中提取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)]};
添加帮助方法,在控制UICollectionViewCell
的视图控制器中返回UICollectionView
重用标识符:
- (NSString *)cellReuseIdentifierAtIndexPath:(NSIndexPath *)indexPath
{
switch (indexPath.item) {
case 0: return @"TodayCell";
case 1: return @"SpecialDayCell";
case 2: return @"NameDayCell";
}
return nil;
}
请务必在cellForItemAtIndexPath
中使用相同的重用标识符:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell =
[collectionView dequeueReusableCellWithReuseIdentifier:
[self cellReuseIdentifierAtIndexPath:indexPath]
forIndexPath:indexPath];
...
最后实施sizeForItemAtIndexPath
:
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *storyboardPrototypeCellSizes =
#import "StoryboardPrototypeCellSizes.h"
return [(NSValue *)storyboardPrototypeCellSizes[
[self cellReuseIdentifierAtIndexPath:indexPath]
] CGSizeValue];
}
此解决方案允许您在故事板中仅定义UICollectionViewCell
原型单元格大小一次,并且在运行时也不会执行任何非App-Store兼容。
****编辑:****您还可以通过添加具有相同内容的另一个脚本并将“collectionViewCell”替换为“collectionReusableView”来获取UICollectionReusableView大小,并将头文件重命名为,例如,StoryboardReusableViewSizes.h
答案 1 :(得分:0)
没有更好的方法来设置单元格大小。单元格大小在UICollectionView中的几个位置使用 - 用于定位,用于滚动指示器。如果用户使用数千个小单元滚动集合,则尽可能快地接收它们非常非常重要。因此创建单元格并询问它的大小不是一个选项。你必须实现collectionView:layout:sizeForItemAtIndexPath:它应该可以快速工作。
答案 2 :(得分:-1)
您是否在UICollectionView
中使用了流量布局?如果是,您可以使用sizeForItemAtIndexPath
协议的UICollectionViewDelegateFlowLayout
方法来提供单元格的大小。如果您在应用中使用OSS组件时遇到问题,可以使用RFQuiltLayout来实现此目的。