ios 设置部分插入时,带有 FlowLayout 的 UICollectionView 不滚动
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12679182/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
UICollectionView with FlowLayout not scrolling when setting section insets
提问by darksky
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
有一个部分插图设置为:
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. I am setting it to that since the collection view doesn't seem to scroll up or down when I insert new items.
我已将高度设置为 3,000,以查看集合视图是否会滚动但不会滚动。我将其设置为这样,因为当我插入新项目时,集合视图似乎不会向上或向下滚动。
UICollectionView
is subclassed from a UIScrollView
, which means I can keep resetting the scroll view content size. Would this work properly?
UICollectionView
是从 a 子类化的UIScrollView
,这意味着我可以不断重置滚动视图内容大小。这会正常工作吗?
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. I have to scroll more and I will be able to see it but it goes back up again to 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? This is a little ridiculous... UITableViews adjust their scroll according to their content automatically.
此外,即使我拥有 +300,最后一行我也只能看到大约 3/4 而不是全部。我必须滚动更多,我才能看到它,但它又回到了 3/4。它有点像滚动刷新,只有当你拖动它时视图才会移动,当你离开它时它会回到原来的位置。为什么会这样?是不是苹果设计的UICollectionView
这么差?这有点荒谬…… UITableViews 会根据它们的内容自动调整它们的滚动条。
回答by rdelmar
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. 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:). My images are 48x48, and I just set my collection view to the bounds of my controller's view. Here is the code so you can compare it to what you have:
在回答你关于 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);
}
回答by simon
Setting the height of the UICollectionView
to 3000 will make your scrolling problem worse. 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. You should set it to the height of the view it is contained in (same as the width).
将 的高度设置UICollectionView
为 3000 会使您的滚动问题变得更糟。如果UICollectionView
3000 像素高,那么只有在其中包含超过 3000 像素的内容时才需要滚动。您应该将其设置为包含它的视图的高度(与宽度相同)。
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.
AFAIK 也不应该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?
我不完全清楚您的问题是什么 - 是不是当您添加超过一个屏幕的项目时,您无法滚动?
回答by dulgan
I've encountered the same problem because I was initializing the elements of my collectionView (i.e. it's DataSource) in the viewWillAppear method.
我遇到了同样的问题,因为我正在 viewWillAppear 方法中初始化我的 collectionView 的元素(即它的 DataSource)。
I finally add just a [self.collectionView reloadData];
and it works just fine!
我最后只添加了一个[self.collectionView reloadData];
,它工作得很好!
Maybe you're in the same case.
或许你也是这种情况。