gpt4 book ai didi

ios - UICollectionview 水平和垂直滚动

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:00:50 25 4
gpt4 key购买 nike

我必须构建一个可水平和垂直滚动的 UICollectionView,我知道网格布局仅沿一个轴滚动,水平或垂直,所以我阅读了一些帖子并尝试了不同的解决方案,但最简单的是将UIScrollView 中的 UICollectionview。通过这种方式,CollectionView 垂直滚动而 UIScrollView 水平滚动。问题是垂直滚动很困难,不流畅,而且经常会停止,直到你再次点击并再次拖动。你能提出一个解决方案吗?谢谢

UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
UIScrollView *backgroundScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
backgroundScroll.scrollEnabled = YES;
[self.view addSubview:backgroundScroll];
_collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(10, 15, 1020, [UIScreen mainScreen].bounds.size.height - 35) collectionViewLayout:layout];
[backgroundScroll addSubview:_collectionView];
_collectionView.contentInset = UIEdgeInsetsMake(0, 0, 50, 0);
_collectionView.scrollEnabled = YES;

我已经实现了这个方法:

- (void)viewDidLayoutSubviews {
backgroundScroll.contentSize = self.collectionView.frame.size;
}

最佳答案

这样做的方法是创建一个自定义的 UICollectionViewLayout 子类。

我最近不得不这样做。

让我去拿文件...等一下...

首先,您不能为此轻易使用 UICollectionViewFlowLayout 的子类。流式布局旨在使内容在一个方向上适合,而在另一个方向上滚动。这不是您想要的。

创建自定义布局来为您执行此操作并不难。

头文件

@interface GridCollectionViewLayout : UICollectionViewLayout

// properties to configure the size and spacing of the grid
@property (nonatomic) CGSize itemSize;
@property (nonatomic) CGFloat itemSpacing;

// this method was used because I was switching between layouts
- (void)configureCollectionViewForLayout:(UICollectionView *)collectionView;

@end

实现

#import "GridCollectionViewLayout.h"

@interface GridCollectionViewLayout ()

@property (nonatomic, strong) NSDictionary *layoutInfo;

@end

@implementation GridCollectionViewLayout

为代码和界面构建器创建初始化...

- (id)init
{
self = [super init];
if (self) {
[self setup];
}

return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self) {
[self setup];
}

return self;
}

设置默认属性值...

- (void)setup
{
self.itemSize = CGSizeMake(50.0, 50.0);
self.itemSpacing = 10.0;
}

之所以使用它是因为我在不同的布局之间切换,但它显示了设置布局所需的内容..

- (void)configureCollectionViewForLayout:(UICollectionView *)collectionView
{
collectionView.alwaysBounceHorizontal = YES;

[collectionView setCollectionViewLayout:self animated:NO];
}

必需的方法。这会迭代项目并为每个项目创建框架 CGRect。将它们保存到字典中。

- (void)prepareLayout
{
NSMutableDictionary *cellLayoutInfo = [NSMutableDictionary dictionary];

NSInteger sectionCount = [self.collectionView numberOfSections];
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];

for (NSInteger section = 0; section < sectionCount; section++) {
NSInteger itemCount = [self.collectionView numberOfItemsInSection:section];

for (NSInteger item = 0; item < itemCount; item++) {
indexPath = [NSIndexPath indexPathForItem:item inSection:section];

UICollectionViewLayoutAttributes *itemAttributes =
[UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
itemAttributes.frame = [self frameForAssessmentAtIndexPath:indexPath];

cellLayoutInfo[indexPath] = itemAttributes;
}
}

self.layoutInfo = cellLayoutInfo;
}

这是一种快速获取给定索引处的帧的便捷方法。

- (CGRect)frameForIndexPath:(NSIndexPath *)indexPath
{
NSInteger column = indexPath.section;
NSInteger row = indexPath.item;

CGFloat originX = column * (self.itemSize.width + self.itemSpacing);
CGFloat originY = row * (self.itemSize.height + self.itemSpacing);

return CGRectMake(originX, originY, self.itemSize.width, self.itemSize.height);
}

计算内容大小的必需方法。这只是将部分或项目的数量乘以大小和间距属性。这就是允许双向滚动的原因,因为内容大小可以大于 Collection View 的宽度和高度。

- (CGSize)collectionViewContentSize
{
NSInteger sectionCount = [self.collectionView numberOfSections];

if (sectionCount == 0) {
return CGSizeZero;
}

NSInteger itemCount = [self.collectionView numberOfItemsInSection:0];

CGFloat width = (self.itemSize.width + self.itemSpacing) * sectionCount - self.itemSpacing;
CGFloat height = (self.itemSize.height + self.itemSpacing) * itemCount - self.itemSpacing;

return CGSizeMake(width, height);
}

必需的方法。这些告诉 Collection View 每个项目需要放置的位置。

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
return self.layoutInfo[indexPath];
}

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSMutableArray *allAttributes = [NSMutableArray array];

[self.layoutInfo enumerateKeysAndObjectsUsingBlock:^(NSIndexPath *indexPath, UICollectionViewLayoutAttributes *attributes, BOOL *stop) {
if (CGRectIntersectsRect(attributes.frame, rect)) {
[allAttributes addObject:attributes];
}
}];

return allAttributes;
}

@end

当然,这种情况下的布局是针对我个人的问题。

布局的工作原理是让每个部分都是一列,每个部分中的项目都是行。所以像这样...

xy = item y in section x

00 10 20 30 ...
01 11 21 31 ...
02 12 22 32 ...
. . . .
. . . .
. . . .

显然,部分或部分中的项目可以有无限数量,因此我必须在两个方向上滚动。

创建布局类后,只需将其设置为 Collection View 的布局即可。您可以在代码 collectionView.collectionViewLayout = myLayout 中执行此操作,也可以在 Interface Builder 中使用 Collection View 上的“布局”属性执行此操作。

关于ios - UICollectionview 水平和垂直滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29302772/

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