gpt4 book ai didi

ios - 如何根据行交替 UICollectionViewCell 背景颜色?

转载 作者:可可西里 更新时间:2023-11-01 05:04:36 25 4
gpt4 key购买 nike

我知道这对于 UITableViewCells 来说相当容易,但我不确定如何使用 UICollectionView 来解决这个问题。

编辑。图片澄清。单元格的文本内容在这里不一样,但它们应该是一样的。
在风景中:



纵向:

enter image description here

我试图根据 cellForItemAtIndexPath: 中索引路径的行属性天真地将单元格文本标签的颜色与单元格的背景颜色切换。方法。然而,索引路径的行属性实际上并不是 UICollectionViewFlowLayout 中的一行。

最佳答案

集合 View 及其布局都不会告诉您项目的“行号”。你必须自己计算。

如果您的所有测量值都是统一的(如果您没有实现任何 UICollectionViewDelegateFlowLayout 方法就是这种情况),您就可以很容易地计算它。

有几个地方可以进行计算并分配颜色。我将向您展示执行此操作的“正确”位置:在布局管理器中。

“Knowing When to Subclass the Flow Layout” section of the Collection View Programming Guide for iOS告诉你你需要做的基本事情,但它非常简单,所以我会引导你完成它。

注意:自 layoutAttributes是一个相当麻烦的标识符,我通常使用pose反而。
UICollectionViewLayoutAttributes子类

首先,我们需要一种方法将背景颜色从布局管理器传递到单元格。正确的方法是通过子类化 UICollectionViewLayoutAttributes .该接口(interface)只添加了一个属性:

@interface MyLayoutAttributes : UICollectionViewLayoutAttributes

@property (nonatomic, strong) UIColor *backgroundColor;

@end

实现需要实现 NSCopying协议(protocol):
@implementation MyLayoutAttributes

- (instancetype)copyWithZone:(NSZone *)zone {
MyLayoutAttributes *copy = [super copyWithZone:zone];
copy.backgroundColor = self.backgroundColor;
return copy;
}

@end
UICollectionViewCell子类

接下来,单元格需要使用 backgroundColor属性。您可能已经有了 UICollectionViewCell子类。您需要实现 applyLayoutAttributes:在你的子类中,像这样:
@implementation MyCell

- (void)applyLayoutAttributes:(MyLayoutAttributes *)pose {
[super applyLayoutAttributes:pose];
if (!self.backgroundView) {
self.backgroundView = [[UIView alloc] init];
}
self.backgroundView.backgroundColor = pose.backgroundColor;
}

@end
UICollectionViewFlowLayout子类

现在您需要创建 UICollectionViewFlowLayout 的子类使用 MyLayoutAttributes而不是 UICollectionViewLayoutAttributes ,并设置 backgroundColor每个 MyLayoutAttributes正确。让我们定义接口(interface)以具有一个属性,该属性是要分配给行的颜色数组:
@interface MyLayout : UICollectionViewFlowLayout

@property (nonatomic, copy) NSArray *rowColors;

@end

我们在实现中需要做的第一件事是指定我们希望它使用的布局属性类:
@implementation MyLayout

+ (Class)layoutAttributesClass {
return [MyLayoutAttributes class];
}

接下来,我们需要覆盖 UICollectionViewLayout的两个方法设置 backgroundColor每个姿势的属性。我们调用 super获取姿势集,然后使用辅助方法设置背景颜色:
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
NSArray *poses = [super layoutAttributesForElementsInRect:rect];
[self assignBackgroundColorsToPoses:poses];
return poses;
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
MyLayoutAttributes *pose = (MyLayoutAttributes *)[super layoutAttributesForItemAtIndexPath:indexPath];
[self assignBackgroundColorsToPoses:@[ pose ]];
return pose;
}

这是实际分配背景颜色的方法:
- (void)assignBackgroundColorsToPoses:(NSArray *)poses {
NSArray *rowColors = self.rowColors;
int rowColorsCount = rowColors.count;
if (rowColorsCount == 0)
return;

UIEdgeInsets insets = self.sectionInset;
CGFloat lineSpacing = self.minimumLineSpacing;
CGFloat rowHeight = self.itemSize.height + lineSpacing;
for (MyLayoutAttributes *pose in poses) {
CGFloat y = pose.frame.origin.y;
NSInteger section = pose.indexPath.section;
y -= section * (insets.top + insets.bottom) + insets.top;
y += section * lineSpacing; // Fudge: assume each prior section had at least one cell
int row = floorf(y / rowHeight);
pose.backgroundColor = rowColors[row % rowColorsCount];
}
}

请注意,此方法做出了几个假设:
  • 它假设滚动方向是垂直的。
  • 它假设所有项目的大小相同。
  • 它假设所有部分都具有相同的插图和行距。
  • 它假设每个部分至少有一个项目。

  • 最后一个假设的原因是一个部分中的所有行都遵循最小行距, 除了 对于最后一行,其后是底部插图。我需要知道当前项目的行之前有多少行。我尝试通过将 Y 坐标除以一行的高度来实现这一点……但每个部分的最后一行都比其他部分短。因此,捏造。

    应用你的新类(class)

    无论如何,现在我们需要使用这些新类。

    首先,我们需要使用 MyLayout而不是 UICollectionViewFlowLayout .如果您在代码中设置集合 View ,只需创建一个而不是 MyLayout并将其分配给集合 View 。如果您在 Storyboard中进行设置,请找到集合 View 的布局(它在 Storyboard大纲中作为集合 View 的子项)并将其自定义类设置为 MyLayout .

    其次,我们需要为布局分配一组颜色。如果您使用 Storyboard,您可能希望在 viewDidLoad 中执行此操作.您可以询问集合 View 的布局,然后将其转换为 MyLayout .我更喜欢使用正确类型的 socket ,连接到 Storyboard中的布局对象。
    @implementation ViewController

    - (void)viewDidLoad {
    [super viewDidLoad];

    self.layout.rowColors = @[
    [UIColor lightGrayColor],
    [UIColor cyanColor],
    ];
    }

    结果

    如果您正确设置了所有内容,您将得到如下结果:

    portrait screen shot

    在横向模式下,它看起来像这样:

    landscape screen shot

    我已经把我的测试项目 in this github repository .

    关于ios - 如何根据行交替 UICollectionViewCell 背景颜色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18317405/

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