简体   繁体   English

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

[英]UICollectionView with FlowLayout not scrolling when setting section insets

I am using a UICollectionView programmatically. 我以编程方式使用UICollectionView。

I've set its frame as follows: 我将其框架设置如下:

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

My UICollectionViewFlowLayout has a section inset set as: 我的UICollectionViewFlowLayout将section inset设置为:

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

I also only have 1 section. 我也只有1节。

I've set the height to be 3,000 to see if the collection view would scroll but it doesn't. 我已将高度设置为3,000,以查看集合视图是否会滚动但不会。 I am setting it to that since the collection view doesn't seem to scroll up or down when I insert new items. 我正在设置它,因为当我插入新项目时,集合视图似乎没有向上或向下滚动。

UICollectionView is subclassed from a UIScrollView , which means I can keep resetting the scroll view content size. UICollectionViewUIScrollView子类,这意味着我可以继续重置滚动视图的内容大小。 Would this work properly? 这会正常吗?

The only issue is that this would work if I know the sizes of all items including how many items are on each row. 唯一的问题是,如果我知道所有项目的大小,包括每行有多少项,这将有效。

If each item had a different size, how would I find out the size of each row? 如果每个项目的大小不同,我如何找出每行的大小? I would need that to add all row sizes and increase the content size height of self.collectionView . 我需要添加所有行大小并增加self.collectionView的内容大小高度。

EDIT 编辑

Even my suggestion above, resetting the content size, does not work properly! 即使我上面的建议,重置内容大小,也无法正常工作! I tried the following when updating my collection view: 我在更新集合视图时尝试了以下操作:

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

This is very ugly though. 这非常难看。 This is because it assumes all my images are of size 200x200px, which fits 3 images per row (hence the division by 3). 这是因为它假设我的所有图像大小为200x200px,每行适合3个图像(因此除以3)。

Furthermore, even with the +300 that I have, the last row I can only see about 3/4 of it and not all of it. 此外,即使我拥有+300,最后一行我只能看到它的3/4而不是全部。 I have to scroll more and I will be able to see it but it goes back up again to 3/4. 我必须滚动更多,我将能够看到它,但它再次回到3/4。 Its kind of like the scroll to refresh, where the view only moves if you drag it and when you leave it bumps back to where it was. 它有点像滚动刷新,如果你拖动它,视图只会移动,当你离开它时它会回到原来的位置。 Why is this happening? 为什么会这样? Is it just that Apple designed UICollectionView so poorly? 苹果设计的UICollectionView只是如此糟糕吗? This is a little ridiculous... UITableViews adjust their scroll according to their content automatically. 这有点荒谬...... UITableViews会根据自己的内容自动调整滚动。

In answering some of your other questions about UICollectionView, I created this demo project, and it scrolls just fine, so I don't know what problem you're having. 在回答关于UICollectionView的其他一些问题时,我创建了这个演示项目,它滚动得很好,所以我不知道你遇到了什么问题。 The only thing I needed to do to make the last row wholly visible was to increase the size of the bottom inset to 90. I also added a completion method to the performBatchUpdates:completion: to automatically scroll so that the last added item is visible (notice that I add some extra items by using performSelector;withObject:afterDelay:). 我需要做的唯一事情是使最后一行完全可见是将底部插入的大小增加到90.我还为performBatchUpdates添加了一个完成方法:完成:自动滚动以便最后添加的项目可见(注意我通过使用performSelector; withObject:afterDelay :)添加了一些额外的项目。 My images are 48x48, and I just set my collection view to the bounds of my controller's view. 我的图像是48x48,我只是将我的集合视图设置为控制器视图的边界。 Here is the code so you can compare it to what you have: 以下是代码,您可以将其与您拥有的代码进行比较:

@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);
}

Setting the height of the UICollectionView to 3000 will make your scrolling problem worse. UICollectionView的高度设置为3000将使您的滚动问题变得更糟。 If the UICollectionView is 3000 pixels tall then it will only ever need to scroll if it has more than 3000 pixels worth of content in it. 如果UICollectionView为3000像素,那么只要它具有超过3000像素的内容,它就只需要滚动。 You should set it to the height of the view it is contained in (same as the width). 您应该将其设置为包含的视图的高度(与宽度相同)。

AFAIK the also should not set the contentSize directly, instead you need to override the - (CGSize)collectionViewContentSize method in a subclass of UICollectionViewLayout , but generally speaking you shouldn't need to change the content size for normal uses. 据我所知的也不宜设置contentSize直接,而不是你需要重写- (CGSize)collectionViewContentSize方法中的一个子类UICollectionViewLayout ,但总体来讲,你不应该需要改变内容大小正常使用。

I'm not totally clear on what your problem is - is it that when you add more than a screens worth of items you can't scroll? 我不清楚你的问题是什么 - 当你添加超过屏幕价值的物品时,你无法滚动?

I've encountered the same problem because I was initializing the elements of my collectionView (ie it's DataSource) in the viewWillAppear method. 我遇到了同样的问题,因为我在viewWillAppear方法中初始化了我的collectionView(即它的DataSource)的元素。

I finally add just a [self.collectionView reloadData]; 我最后只添加了一个[self.collectionView reloadData]; and it works just fine! 它工作得很好!

Maybe you're in the same case. 也许你的情况是一样的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM