gpt4 book ai didi

ios - 自定义 UICollectionViewLayout : Get size of a certain cell

转载 作者:塔克拉玛干 更新时间:2023-11-01 19:08:25 25 4
gpt4 key购买 nike

我正在根据他们的设计规范为客户构建自定义 UICollectionViewLayout 以实现他们想要的外观和流程。我遇到了一个问题,涉及我定位的单元格的大小。

单元格的大小可能不同,我要使用的布局样式需要特定的间距要求,以便单元格不会彼此重叠,这意味着在重载 -layoutAttributesForItemAtIndexPath : 在布局中我想查看项目大小,以便可以正确设置和用于计算。

我遇到的问题是,UICollectionView 似乎依赖于此方法来设置单元格的大小,因为在我设置属性之前,我使用任何方法从中获取大小单元格将始终生成 CGSizeZero

这是我必须设计的东西吗? Storyboard 中单元格的大小不可访问(至少使用我目前知道的方法)所以我无法解决这个问题,只能使用特定的宽度/高度(仅适用于一个两个可能的单元格)来测试和编写布局代码。

最终:如何在 UICollectionViewLayout 中获取 UICollectionViewCell 的大小以用于计算?

编辑:

我试过以下方法:

CGRect frame = [[self.collectionView cellForItemAtIndexPath:path] frame];
CGSize size = [[self.collectionView cellForItemAtIndexPath:path] intrinsicContentSize];
CGRect frame = [[[self.collectionView cellForItemAtIndexPath:path] contextView] frame];

最佳答案

我从来没有找到一种方法来避免在代码中重复计算大小。这是我通常做的:

获取布局中的尺寸:

布局可以与其 Collection View 对话以查找尺寸(以及诸如最小项间间距等)。您可以在 -prepareLayout-layoutAttributesForItemAtIndexPath: 中执行类似的操作:

if ([self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:sizeForItemAtIndexPath:)]) {
id<UICollectionViewDelegateFlowLayout> delegate = (id<UICollectionViewDelegateFlowLayout>) self.collectionView.delegate;
size = [delegate collectionView:self.collectionView layout:self sizeForItemAtIndexPath:indexPath];
}
else {
size = self.itemSize;
}

现在,您的 Collection View 委托(delegate)只需要能够响应 collectionView:layout:sizeForItemAtIndexPath:,即使没有自定义布局类也是必需的。

首先计算尺寸:

有时提供正确的尺寸有点麻烦。没有实际实例化和布局单元格的大小的神奇方法,所以我总是自己编写代码。我的大多数 Collection View 单元格都有一个类方法:

+ (CGSize)sizeWithItem:(id<MyDisplayableItem>)item;

当我需要一个单元格的大小时,我从我的 Collection View 委托(delegate)中调用它:

-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
Note* note = self.notes[indexPath.item];
CGSize result = [CSDetailNoteCell sizeWithNote:note];
// or [MyCell sizeWithItem:myItem andMyOtherItem:somethingElse]
return result;
}

不幸的是,+sizeWithItem: 方法不是免费提供的,但至少它将尺寸计算封装在 Cell 类中。我倾向于在类中存储一个常量,表示永不改变的事物的大小(填充,可能是图像)。然后,我将该固定大小与需要动态计算的内容结合起来以找到最终大小。动态内容通常包括对 NSString 的 -boundingRectWithSize:options:attributes:context: 等的一些调用。

样本量计算:

此示例使用宽度始终为 320 的单元格,但我认为这足以说明要点。这是来自 CSDetailNoteCell.m 的代码。

static CGFloat const CSDetailNoteCellWidth = 320.f;
static CGFloat const CSDetailNoteCellHeightConstant =
10 + // top padding
16 + // date label height
0 + // padding from date label to textview
8 + // textview top padding
8 + // textview bottom padding
22 // bottom padding
;

...

+ (CGFloat)textWidth {
return CSDetailNoteCellTextViewWidth - 10; // internal textview padding
}

+ (CGSize)sizeWithNote:(CSNote *)note {
CGFloat textHeight = [self _textHeightWithText:note.text];
CGSize result = CGSizeMake(CSDetailNoteCellWidth, CSDetailNoteCellHeightConstant + textHeight);
return result;
}

+ (CGFloat)_textHeightWithText:(NSString*)text {
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];

CGSize maxSize = CGSizeMake(CSDetailNoteCell.textWidth, CGFLOAT_MAX);
NSDictionary* attributes = @{NSFontAttributeName: CSDetailNoteCell.font, NSParagraphStyleAttributeName: paragraphStyle};
CGRect boundingBox = [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil];
CGFloat textHeight = ceilf(boundingBox.size.height);
return textHeight;
}

关于ios - 自定义 UICollectionViewLayout : Get size of a certain cell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22570767/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com