簡體   English   中英

UICollectionViewCell在設備旋轉時調整大小

[英]UICollectionViewCell resizing on device rotation

我在ViewController中嵌入了一個非常簡單的UICollectionView。

UICollectionView使用自動布局(在IB中定義)來占用ViewController中的整個空間。

我的UICollectionViewCell具有相同的大小,它們占據了UICollectionView的整個空間,因為我只希望在ViewController中顯示一個單元格。 UICollectionViewCell僅顯示一個UIImage(嵌入在UIScrollView中以進行縮放)。

除非設備旋轉,否則它工作正常。 出現錯誤消息:

未定義UICollectionViewFlowLayout的行為,因為:項目高度必須小於UICollectionView的高度減去該部分插入的上限值和下限值,減去內容插入的上限值和下限值。 相關的UICollectionViewFlowLayout實例為,並附加到; 動畫= {bounds.origin =; bounds.size =; position =; }; 層=; 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(to:with :)(375.0,667.0)viewWillLayoutSubviews()(667.0,375.0)viewDidLayoutSubviews()(667.0,375.0)

該錯誤僅在viewDidLayoutSubviews()之后顯示。 我試圖在viewDidLayoutSubviews()中調用theFlowLayout.invalidateLayout(),但它不會改變問題。

我讀過其他類似的問題,但找不到答案:-(

謝謝你的幫助,

塞巴斯蒂安

我還沒有找到最好的解決方案,但至少可以奏效。

我使用viewWillTransition計算單元格的索引並在旋轉后重置偏移量。 為避免動畫效果不佳,我將Alpha設置為0,並在動畫的開始處將其設置為1,然后在動畫結束時將其設置為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
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM