2016-11-05 2 views
0

매우 간단한 UICollectionView가 ViewController에 포함되어 있습니다.장치 회전시 UICollectionViewCell 크기 조정

UICollectionView는 자동 레이아웃 (IB에서 정의)을 사용하여 ViewController의 전체 공간을 차지합니다.

내 UICollectionViewCell은 모두 동일한 크기이며 ViewController에 하나의 셀만 표시되기 때문에 UICollectionView의 전체 공간을 차지합니다. UICollectionViewCell은 확대/축소를 위해 UIScrollView에 포함 된 UIImage 만 표시합니다.

장치가 회전하는 경우를 제외하고는 정상적으로 작동합니다. 때문에 UICollectionViewFlowLayout의 동작이 정의되지 않은

:이 오류 메시지의 이 항목의 높이가 UICollectionView 마이너스 상단 섹션 세트 및 하단 값의 높이보다 작아야은 마이너스 콘텐츠 상단 세트 및 바닥 값. 해당 UICollectionViewFlowLayout 인스턴스가이며에 연결되어 있습니다. 애니메이션 = {bounds.origin =; bounds.size =; 위치 =; }; layer =; contentOffset : {0, 0}; contentSize : {4875, 323}> 컬렉션보기 레이아웃 :.

상당히 명확합니다. 새 높이/너비에 맞게 UICollectionViewCell의 크기를 조정해야합니다. 회전 후 UICollectionViewCell은 적절한 높이/너비로 표시되지만 애니메이션은 좋지 않습니다.

@IBOutlet weak var theCollectionView: UICollectionView! 
@IBOutlet weak var theFlowLayout: UICollectionViewFlowLayout! 
    override func viewDidLoad() { 
    super.viewDidLoad() 

    //theCollectionView.delegate = self 
    theCollectionView.dataSource = self 
    automaticallyAdjustsScrollViewInsets = false 
    theFlowLayout.itemSize = theCollectionView.frame.size 
    theFlowLayout.sectionInset = UIEdgeInsetsMake(0,0,0,0) 
    theFlowLayout.minimumLineSpacing = 0.0 
    theCollectionView.reloadData() 
} 


override func viewWillAppear(_ animated: Bool) { 
    super.viewWillAppear(animated) 
} 

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { 
    super.viewWillTransition(to: size, with: coordinator) 
    print("\(#function) \(view.frame.size)") 
    coordinator.animate(alongsideTransition: nil, completion: { 
     _ in 
     self.theFlowLayout.itemSize = self.theCollectionView.frame.size 
    })   
} 

override func viewWillLayoutSubviews() { 
    super.viewWillLayoutSubviews() 
    print("\(#function) \(view.frame.size)") 
} 

override func viewDidLayoutSubviews() { 
    super.viewDidLayoutSubviews() 
    print("\(#function) \(view.frame.size)") 
} 

질문은, 어떻게 부드러운 애니메이션을 경고를 방지하고 얻을 수있는 UICollectionViewCell 변화를 수행 할 때 : 여기

코드입니다 에 viewWillTransition (:와 :) (375.0, 667.0) viewWillLayoutSubviews() (667.0, 375.0) viewDidLayoutSubviews() (667.0, 375.0)

장치 회전이 발생

, 나는 다음을 볼 수 있습니다

오류는 viewDidLayoutSubviews() 바로 뒤에 표시됩니다. viewDidLayoutSubviews()에서 theFlowLayout.invalidateLayout()을 호출하려고 시도했지만 문제가 변경되지 않았습니다.

나는 다른 사람과 비슷한 질문을 읽고하지만 난 못 찾았 최적의 솔루션을 도와

감사합니다 :-(내 대답은,

세바스티안

답변

0

를 찾을 수 없습니다하지만 적어도 작동

viewWillTransition을 사용하여 셀의 인덱스를 계산하고 회전 후 오프셋을 다시 설정합니다. 불량한 애니메이션을 방지하기 위해 애니메이션의 끝에서 알파를 0으로 설정하고 처음에는 1로 설정하고

viewWillLayoutSubviews는 새 셀 크기를 설정하기 위해 UICollectionViewFlowLayout 및 viewDidLayoutSubviews의 레이아웃을 무효화하는 데 사용됩니다.

다른 사람들에게 도움이 될지 모르지만 더 나은 해결책이 있다면 공유하십시오.

@IBOutlet weak var theCollectionView: UICollectionView! { 
    didSet { 
     theCollectionView.backgroundColor = UIColor.black 
     theCollectionView.delegate = self 
     theCollectionView.dataSource = self 
    } 
} 

@IBOutlet weak var theFlowLayout: UICollectionViewFlowLayout! { 
    didSet { 
     theFlowLayout.itemSize = theCollectionView.frame.size 
     theFlowLayout.sectionInset = UIEdgeInsetsMake(0,0,0,0) 
     theFlowLayout.minimumLineSpacing = 0.0 
    } 
} 

var assets:[PHAsset]! 
var startAssetIndex = 0 

override func viewDidLoad() { 
    super.viewDidLoad() 
    view.backgroundColor = UIColor.black 
    automaticallyAdjustsScrollViewInsets = false 
    theCollectionView.reloadData() 
} 


override func viewWillAppear(_ animated: Bool) { 
    super.viewWillAppear(animated) 
    theCollectionView.scrollToItem(at: IndexPath(row:startAssetIndex, section:0), at: .left, animated: true) 
} 


/// Resize the collectionView during device rotation 
/// 
/// - Parameters: 
/// - size: New size of the viewController 
/// - coordinator: coordinator for the animation 
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { 
    super.viewWillTransition(to: size, with: coordinator) 

    // Compute the index of the image/video currently displayed 
    let offset = self.theCollectionView.contentOffset; 
    let index = round(offset.x/self.theCollectionView.bounds.size.width); 

    // hide the collection view to avoid horrible animation during the rotation 
    // animation is horrible due to the offset change 
    theCollectionView.alpha = 0.0 
    coordinator.animate(alongsideTransition: nil, completion: { 
     _ in 
     // display the collectionView during the animation 
     self.theCollectionView.alpha = 1.0 

     // compute the new offset based on the index and the new size 
     let newOffset = CGPoint(x: index * self.theCollectionView.frame.size.width, y: offset.y) 
     self.theCollectionView.setContentOffset(newOffset, animated: false) 
    }) 
} 


/// Invalidate the layout of the FlowLayout, it's mandatory for the rotation 
override func viewWillLayoutSubviews() { 
    theFlowLayout.invalidateLayout() 
    super.viewWillLayoutSubviews() 
} 


/// Set the size of the items (mandatory for the rotation) 
override func viewDidLayoutSubviews() { 
    super.viewDidLayoutSubviews() 
    theFlowLayout.itemSize = theCollectionView.frame.size 
} 
관련 문제