web-dev-qa-db-ja.com

セクションインセットを設定するときにFlowLayoutがスクロールしない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であり、1行あたり3つの画像に収まると想定しているためです(したがって、3で除算します)。

さらに、私が持っている+300でも、最後の行はその約3/4しか見ることができず、すべてではありません。もっとスクロールする必要があり、それを見ることができますが、再び3/4に戻ります。スクロールして更新するようなもので、ビューはドラッグした場合にのみ移動し、離れると元の場所に戻ります。なんでこんなことが起こっているの? Apple設計されたUICollectionViewがあまりにも貧弱なだけですか?これは少しばかげています... UITableViewsはコンテンツに応じてスクロールを自動的に調整します。

10
darksky

UICollectionViewに関する他のいくつかの質問に答える際に、私はこのデモプロジェクトを作成しましたが、スクロールは問題ないので、どのような問題が発生しているのかわかりません。最後の行を完全に表示するために必要なのは、下部の挿入図のサイズを90に増やすことだけでした。また、performBatchUpdates:completion:に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);
}
13
rdelmar

UICollectionViewの高さを3000に設定すると、スクロールの問題が悪化します。 UICollectionViewの高さが3000ピクセルの場合、3000ピクセルを超えるコンテンツが含まれている場合にのみ、スクロールする必要があります。含まれているビューの高さ(幅と同じ)に設定する必要があります。

AFAIKもcontentSizeを直接設定するべきではありません。代わりに、UICollectionViewLayoutのサブクラスの- (CGSize)collectionViewContentSizeメソッドをオーバーライドする必要がありますが、一般的に言えば、変更する必要はありません。通常の使用のためのコンテンツサイズ。

私はあなたの問題が何であるかについて完全に明確ではありません-それはあなたが画面に相当するアイテム以上を追加するとスクロールできないということですか?

9
simon

ViewWillAppearメソッドでcollectionViewの要素(つまり、DataSource)を初期化していたため、同じ問題が発生しました。

最後に[self.collectionView reloadData];だけを追加しましたが、問題なく動作します。

たぶんあなたは同じ場合です。

2
dulgan