4

UICollectionViewiOS 6の内部から無限の水平スクロールと垂直スクロールを実装しようとしています。

StackOverflow にも同様の質問がありますが、最も深い質問は、Apple の WDC ビデオに従い、スクロールではなくコレクションで実装することです。これと同様の質問で行われた他のコメントに基づいてデザインを作成しましたが、それでも滑らかに見せることができません。

私は基本的に、HBO GO iPad アプリの動作を模倣しようとしています。これは、ショーのグリッドを表示し、任意の方向にスクロールできるようにします。最後に到達すると、ショーがラップされるだけなので、無限にスクロールしているように感じます。 .

私が行ったことは、UICollectionViewセルをグリッドに配置するカスタム レイアウトを作成することです。UICollectionView次に、上書きしたメソッドをサブクラス化し、Eliza の WDC ビデオ ショーと同じように関数layoutSubviewsを作成しました。reecenterIfNecessaryこれは機能し、無限の「スクロール」を取得しますが、コンテンツは変更されません。

そこで、View Controller を指すデリゲートを作成し、それがラップするたびにデリゲートにそのデータ ソースを移動するように指示しましたが、それは反映されていませUICollectionView[self reloadData]。 "。無限にスクロールします。

しかし、私が呼び出すreloadDataので、遅延が目立ち、スクロールバーがちらつきます(「コンテンツ」が「リロード」されているため)。これは容認できません。回避する方法がわかりません。

どんな助けでも大歓迎です。役立つ場合に備えてrecenterIfNecessary関数を含めました。

- (void) recenterIfNecessary{

CGPoint currentOffset = [self contentOffset];
CGFloat contentHeight = [self contentSize].height;
CGFloat contentWidth = [self contentSize].width;

//calc center point which would leave same amount of content on both sides
CGFloat centerY = (contentHeight - [self bounds].size.height) / 2.0;
CGFloat centerX = (contentWidth - [self bounds].size.width) / 2.0;

if (currentOffset.x == 0 && currentOffset.y == 0){
    //assume this is first load. Set offset to content center.
    self.contentOffset = CGPointMake(centerX, centerY);
    return;
}

//distance from center is abs of where we are and where we want to be:
CGFloat offsetY = centerY-currentOffset.y;
CGFloat offsetX = centerX-currentOffset.x;

//now we decide if we want to recenter
int deltaX = 0;
int deltaY = 0;
if (fabs(offsetX) > CELL_WIDTH){

    if (offsetX < 0){
        deltaX = -ceil(offsetX / CELL_WIDTH);
    }else{
        deltaX = -floor(offsetX / CELL_WIDTH);
    }
    offsetX += offsetX + (CELL_WIDTH * deltaX);
    self.contentOffset = CGPointMake(centerX, currentOffset.y);
}
if (fabs(offsetY) > CELL_HEIGHT){

    if (offsetY < 0){
        deltaY = -ceil(offsetY / CELL_HEIGHT);
    }else{
        deltaY = -floor(offsetY / CELL_HEIGHT);
    }

    offsetY += offsetY + (CELL_HEIGHT * deltaY);

    self.contentOffset = CGPointMake(currentOffset.x, centerY);

}
if (fabs(offsetX) > CELL_WIDTH || fabs(offsetY) > CELL_HEIGHT){
    //move subviews to reflect scrolling
    for (UIView *subview in self.subviews) {
        CGPoint center = subview.center;
        center.x += offsetX;
        center.y += offsetY;
        subview.center = center;
    }

    if ([self.infiniteDataModelDelegate conformsToProtocol:@protocol(InfiniteDataModelProtocol)]){
        //moves the data model to reflect "scrolling"
        [self.infiniteDataModelDelegate contentDidChangeModelDeltaX:deltaX deltaY:deltaY];
    }
    [self reloadData];
}
}
4

2 に答える 2

1

全方向に無限にスクロールするビューを提供するライブラリをまとめました。ユーザーがスクロールすると、フレームワークがタイルをレイアウトし、タイルのプレゼンテーションをセットアップできるようにデリゲートに通知します。パフォーマンスに関しては、フレームワークは遅延を導入しません: フル 60 fps.

無限にスクロールする壁に Flickr の画像を表示するサンプル アプリを含むフレームワークは、https ://github.com/vovagalchenko/scroll-for-days にあります。さらに、サンプル アプリの動作のビデオを次に示します: https://cloud.box.com/s/d6bgvlot175au5a3jeh5

于 2014-03-10T02:16:31.423 に答える
0

このアプローチを試しましたか?

-(void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath{
    if ([self.products count] > 8 && indexPath.row == [self.products count] - 8) {
        [self loadMoreItems];
        [self.collectionView reloadData];

    }
}
于 2013-09-07T22:21:42.943 に答える