UICollectionView
とUICollectionViewFlowLayout
を使用しています。
各セルのサイズを設定します
collectionView:layout:sizeForItemAtIndexPath:
ポートレートからランドスケープに切り替えるとき、セル間にパディングスペースを残さずに、CollectionViewのサイズに完全に合うように各セルのサイズを調整したいと思います。
質問:
1)回転イベント後にセルのサイズを変更する方法は?
2)さらに良いことに、セルが常に画面のサイズ全体に収まるレイアウトを作成する方法は?
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が水平方向にスクロールする場合は高さを使用し、垂直方向にスクロールする場合は幅を使用します。
performBatchUpdates:completion:
による追加のアニメーションが必要ない場合は、invalidateLayout
を使用して、collectionViewLayoutを強制的に再読み込みします。
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
[self.collectionView.collectionViewLayout invalidateLayout];
}
2つのUICollectionViewFlowLayoutを使用して解決しました。 1つは縦向き、もう1つは横向きです。 -viewDidLoadでコレクションビューに動的に割り当てます
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];
}
}
コレクションビューのセルサイズを設定する簡単な方法があります。
UICollectionViewFlowLayout *layout = (id) self.collectionView.collectionViewLayout;
layout.itemSize = CGSizeMake(cellSize, cellSize);
ただし、アニメート可能かどうかはわかりません。
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)
}
autolayout
を使用している場合は、フローレイアウトサブクラスでoffset
を回転および調整するときに、View Controllerでinvalidate layout
する必要があります。
だから、あなたの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);
}
}
}