设置节插入时,带有FlowLayout的UICollectionView不会滚动

时间:2012-10-01 18:49:15

标签: objective-c ios ipad uicollectionview

我正在以编程方式使用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,以查看集合视图是否会滚动但不会。我正在设置它,因为当我插入新项目时,集合视图似乎没有向上或向下滚动。

UICollectionViewUIScrollView的子类,这意味着我可以继续重置滚动视图的内容大小。这会正常吗?

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

如果每个项目的大小不同,我如何找出每行的大小?我需要添加所有行大小并增加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。它有点像滚动刷新,如果你拖动它,视图只会移动,当你离开它时它会回到原来的位置。为什么会这样?只是Apple设计UICollectionView这么糟糕吗?这有点荒谬...... UITableViews会根据自己的内容自动调整滚动。

3 个答案:

答案 0 :(得分:13)

在回答关于UICollectionView的其他一些问题时,我创建了这个演示项目,它滚动得很好,所以我不知道你遇到了什么问题。我需要做的唯一事情是使最后一行完全可见是将底部插入的大小增加到90.我还为performBatchUpdates添加了一个完成方法:完成:自动滚动以便最后添加的项目可见(注意我通过使用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);
}

答案 1 :(得分:9)

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

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

我不清楚你的问题是什么 - 当你添加超过屏幕价值的物品时,你无法滚动吗?

答案 2 :(得分:2)

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

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

也许你的情况也是如此。