[ios] 다른 장치 방향에서 UICollectionViewCell 크기 변경

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:sizeForItemAtIndexPathcollectionView 경계의 높이 또는 너비를 화면에 맞출 셀 수로 나누십시오. collectionView가 가로로 스크롤되는 경우 높이를 사용하고 세로로 스크롤하는 경우 너비를 사용하십시오.


답변

에 의해 추가 애니메이션을 가져 오지 않으려면을 performBatchUpdates:completion:사용 invalidateLayout하여 collectionViewLayout을 강제로 다시로드하십시오.

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    [self.collectionView.collectionViewLayout invalidateLayout];
}


답변

두 개의 UICollectionViewFlowLayout을 사용하여 해결했습니다. 하나는 세로 용이고 다른 하나는 가로 용입니다. -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];
    }
}


답변

컬렉션보기 셀 크기를 설정하는 간단한 방법이 있습니다.

UICollectionViewFlowLayout *layout = (id) self.collectionView.collectionViewLayout;
layout.itemSize = CGSizeMake(cellSize, cellSize);

그래도 애니메이션 가능한지 확실하지 않습니다.


답변

Swift : 화면 높이의 n % 인 Collection View Cell

뷰 높이의 특정 비율 인 셀이 필요했고 장치 회전에 따라 크기가 조정되었습니다.

위의 도움으로 여기에 해결책이 있습니다.

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필요합니다 .invalidate layoutoffset

따라서 뷰 컨트롤러에서-

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);
    }
    }
}


답변