100

UICollectionViewwithを使用していUICollectionViewFlowLayoutます。

各セルのサイズを

collectionView:layout:sizeForItemAtIndexPath:

縦向きから横向きに切り替えるとき、セル間にパディングスペースを残さずに、各セルのサイズを CollectionView のサイズに完全に合うように調整したいと思います。

質問:

1) 回転イベント後にセルのサイズを変更するには?

2) さらに良いことに、セルが常に画面全体のサイズに収まるレイアウトを作成するにはどうすればよいですか?

4

6 に答える 6

201

1) 複数のレイアウト オブジェクトを維持して交換することもできますが、もっと簡単な方法があります。以下をUICollectionViewControllerサブクラスに追加し、必要に応じてサイズを調整します。

- (CGSize)collectionView:(UICollectionView *)collectionView
                  layout:(UICollectionViewLayout *)collectionViewLayout
  sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{    
    // Adjust cell size for orientation
    if (UIDeviceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
        return CGSizeMake(170.f, 170.f);
    }
    return CGSizeMake(192.f, 192.f);
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    [self.collectionView performBatchUpdates:nil completion:nil];
}

呼び出す-performBatchUpdates:completion:と、レイアウトが無効になり、アニメーションでセルのサイズが変更されます (実行する追加の調整がない場合は、両方のブロック パラメーターに nil を渡すだけでかまいません)。

2) 項目のサイズを にハードコーディングする代わりに-collectionView:layout:sizeForItemAtIndexPath、collectionView の境界の高さまたは幅を、画面に収めたいセルの数で割ります。collectionView が水平にスクロールする場合は高さを使用し、垂直にスクロールする場合は幅を使用します。

于 2012-12-01T05:10:24.567 に答える
33

によって追加のアニメーションを表示したくない場合はperformBatchUpdates:completion:、を使用invalidateLayoutしてcollectionViewLayoutを強制的に再ロードします。

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    [self.collectionView.collectionViewLayout invalidateLayout];
}
于 2013-02-08T16:20:31.773 に答える
13

2つのUICollectionViewFlowLayoutを使用して解決しました。1 つはポートレート用、もう 1 つはランドスケープ用です。-viewDidLoad で動的に collectionView に割り当てます

self.portraitLayout = [[UICollectionViewFlowLayout alloc] init];
self.landscapeLayout = [[UICollectionViewFlowLayout alloc] init];

UIInterfaceOrientation orientationOnLunch = [[UIApplication sharedApplication] statusBarOrientation];

if (UIInterfaceOrientationIsPortrait(orientationOnLunch)) {
    [self.menuCollectionView setCollectionViewLayout:self.portraitLayout];
} else {
    [self.menuCollectionView setCollectionViewLayout:self.landscapeLayout];
}

次に、 collectionViewFlowLayoutDelgate メソッドを次のように変更しました

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
    CGSize returnSize = CGSizeZero;

    if (collectionViewLayout == self.portraitLayout) {
        returnSize = CGSizeMake(230.0, 120.0);
    } else {
        returnSize = CGSizeMake(315.0, 120.0);
    }

    return returnSize;
}

最後に、ローテーションでレイアウトを別のレイアウトに切り替えます

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
    if (UIInterfaceOrientationIsPortrait(fromInterfaceOrientation)) {
        [self.menuCollectionView setCollectionViewLayout:self.landscapeLayout animated:YES];
    } else {
        [self.menuCollectionView setCollectionViewLayout:self.portraitLayout animated:YES];
    }
}
于 2012-11-28T13:38:21.120 に答える
7

Swift : 画面の高さの n% であるコレクション ビュー セル

ビューの高さの特定の割合であり、デバイスの回転に合わせてサイズが変更されるセルが必要でした。

上記の助けを借りて、ここに解決策があります

override func viewDidLoad() {
    super.viewDidLoad()
    automaticallyAdjustsScrollViewInsets = false
    // if inside nav controller set to true
}

override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
    collectionViewLayout.invalidateLayout()
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
    return CGSize(width: 100, height: collectionView.frame.height * 0.9)
}
于 2015-11-07T23:23:36.753 に答える
2

を使用している場合は、フローレイアウトサブクラスで回転および調整するときにビューコントローラーで行うautolayout必要があります。invalidate layoutoffset

だから、あなたのView Controllerで -

override func willRotateToInterfaceOrientation(toInterfaceOrientation:     UIInterfaceOrientation, duration: NSTimeInterval) {
    self.galleryCollectionView.collectionViewLayout.invalidateLayout()
}

そしてあなたのFlowLayout Subclass

override func prepareLayout() {
    if self.collectionView!.indexPathsForVisibleItems().count > 0{
    var currentIndex : CGFloat!
    currentIndex = CGFloat((self.collectionView!.indexPathsForVisibleItems()[0] as! NSIndexPath).row)
    if let currentVal = currentIndex{
        self.collectionView!.contentOffset = CGPointMake(currentIndex * self.collectionView!.frame.width, self.collectionView!.contentOffset.y);
    }   
    }     
}
于 2015-08-16T11:43:40.350 に答える