11

我正在以编程方式使用 UICollectionView。

我将其框架设置如下:

UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 100, self.view.frame.size.width, 3000) collectionViewLayout:flowLayout];

UICollectionViewFlowLayout的部分插图设置为:

flowLayout.sectionInset = UIEdgeInsetsMake(20.0, 20.0, 100.0, 20.0);

我也只有1节。

我已将高度设置为 3,000 以查看集合视图是否会滚动,但不会滚动。我将其设置为,因为当我插入新项目时集合视图似乎没有向上或向下滚动。

UICollectionView是从 a 子类化的UIScrollView,这意味着我可以继续重置滚动视图内容大小。这会正常工作吗?

唯一的问题是,如果我知道所有项目的大小,包括每行有多少项目,这将起作用。

如果每个项目的大小不同,我将如何找出每一行的大小?我需要它来添加所有行大小并增加self.collectionView.

编辑

即使我上面的建议,重置内容大小,也不能正常工作!更新我的收藏视图时,我尝试了以下操作:

 int numberOfRows = self.dataArray.count / 3;
self.collectionView.contentSize = CGSizeMake(self.view.frame.size.width, (numberOfRows * 200) + 300);

不过,这很丑陋。这是因为它假设我所有的图像的大小都是 200x200px,每行适合 3 个图像(因此除以 3)。

此外,即使我有 +300,最后一行我也只能看到大约 3/4,而不是全部。我必须滚动更多,我才能看到它,但它又回到了 3/4。它有点像滚动刷新,只有当你拖动它时视图才会移动,当你离开它时,它会撞回原来的位置。为什么会这样?只是苹果设计UICollectionView的这么差吗?这有点荒谬...... UITableViews 根据他们的内容自动调整他们的滚动。

4

3 回答 3

13

在回答你关于 UICollectionView 的其他一些问题时,我创建了这个演示项目,它滚动得很好,所以我不知道你遇到了什么问题。为了使最后一行完全可见,我唯一需要做的就是将底部插图的大小增加到 90。我还在 performBatchUpdates:completion: 中添加了一个完成方法,以自动滚动以便最后添加的项目可见(请注意,我使用 performSelector;withObject:afterDelay:) 添加了一些额外的项目。我的图像是 48x48,我只是将我的收藏视图设置为控制器视图的边界。这是代码,因此您可以将其与您所拥有的进行比较:

@interface ViewController () <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout> {
NSMutableArray *newData;
}
 @property (nonatomic, retain) UICollectionView *collectionView;
 @property (nonatomic, retain) NSMutableArray *results;
 @end

@implementation ViewController

- (void)viewDidLoad {
    self.results = [NSMutableArray array];
    int i = 11;
    while (i<91) {
        UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"New_PICT00%d.jpg",i]];
        [self.results addObject:image];
        i++;
    }

    UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
    //flowLayout.scrollDirection =  UICollectionViewScrollDirectionHorizontal;

    self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:flowLayout];
    self.collectionView.dataSource = self;
    self.collectionView.delegate = self;
    self.view.backgroundColor = [UIColor blackColor];
    [self.view addSubview:self.collectionView];
    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"Cell"];
    //[self.collectionView registerClass:[RDCell class] forCellWithReuseIdentifier:@"myCell"];
    [self.collectionView reloadData];

    [self performSelector:@selector(addNewImages:) withObject:nil afterDelay:3];
}

-(void)addNewImages:(id)sender {
    newData = [NSMutableArray array];
    int i = 102;
    while (i<111) {
        UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"New_PICT0%d.jpg",i]];
        [newData addObject:image];
        i++;
    }
    [self addNewCells];
}

-(void)addNewCells {
    NSMutableArray *arrayWithIndexPaths = [NSMutableArray array];
    [self.collectionView performBatchUpdates:^{
        int resultsSize = [self.results count];
        [self.results addObjectsFromArray:newData];
        for (int i = resultsSize; i < resultsSize + newData.count; i++)
            [arrayWithIndexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
        [self.collectionView insertItemsAtIndexPaths:arrayWithIndexPaths];
    }
    completion: ^(BOOL finished){
        [self.collectionView scrollToItemAtIndexPath:arrayWithIndexPaths.lastObject atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:YES];
    }];
}


- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section {
    return [self.results count];
}

- (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView {
    return 1;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
    //cell.iv.image = [self.results objectAtIndex:indexPath.row];
    cell.backgroundColor = [UIColor colorWithPatternImage:[self.results objectAtIndex:indexPath.row]];
    return cell;
}


- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    UIImage *image = [self.results objectAtIndex:indexPath.row];
    return CGSizeMake(image.size.width, image.size.height);
}

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    return UIEdgeInsetsMake(10, 10, 90, 10);
}

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"Selected Image is Item %d",indexPath.row);
}
于 2012-10-01T19:06:41.603 回答
9

将高度设置UICollectionView为 3000 会使您的滚动问题变得更糟。如果它的UICollectionView高度为 3000 像素,那么只有在其中包含超过 3000 像素的内容时才需要滚动。您应该将其设置为它所包含的视图的高度(与宽度相同)。

AFAIK 也不应该contentSize直接设置,而是您需要覆盖 的- (CGSize)collectionViewContentSize子类中的方法UICollectionViewLayout,但一般来说,您不需要更改正常使用的内容大小。

我不完全清楚你的问题是什么 - 当你添加超过一个屏幕的项目时你不能滚动?

于 2012-10-04T04:24:21.550 回答
2

我遇到了同样的问题,因为我在 viewWillAppear 方法中初始化了我的 collectionView 的元素(即它的 DataSource)。

我最后只添加了一个[self.collectionView reloadData];,它工作得很好!

也许你是同样的情况。

于 2012-11-07T09:39:27.007 回答