1

在我的應用程序中,我有一個全屏分頁集合視圖,每個單元格也需要全屏,因此集合視圖佈局的項目大小需要具有相同的大小作爲視圖控制器視圖的邊界大小。要做到這一點,在viewDidLayoutSubviews我只是設置項目大小,它按預期工作。當我顯示此屏幕時,viewDidLayoutSubviews被調用3次,並且iPhone 7每次視圖的邊界大小爲375.0 x 667.0。單元格大小與預期相同。更改流佈局的項目後單元格大小不更新大小

但是,當使用3D Touch偷看和彈出來呈現此屏幕時,單元格的大小不像預期的那樣大,無論是在偷看還是彈出時。 viewDidLayoutSubviews被稱爲4倍,這些邊界尺寸:
--- PEEK觸發---
375.0 X 569.524495677234
375.0 X 569.524495677234
375.0 X 720.821325648415
---彈出觸發---
375.0 X 667.0

查看時,集合視圖是「全屏」,如預期的那樣,高度爲721,單元格的期望寬度爲375,但單元格高度爲569時應爲721.彈出時,預期集合視圖高度變爲667,但單元格高度仍然爲569.

設置itemSize後,我試過撥打collectionView.layoutIfNeeded(),但結果是一樣的。爲什麼收集視圖沒有在這裏更新單元大小?

override func viewDidLayoutSubviews() { 
    super.viewDidLayoutSubviews() 

    print("\(view.bounds.width) x \(view.bounds.height)") 

    let boundsSize = CGSize(width: Int(view.bounds.width), height: Int(view.bounds.height)) 
    let flowLayout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout 

    if flowLayout.itemSize != boundsSize { 
     flowLayout.itemSize = boundsSize 

     collectionView.layoutIfNeeded() //this doens't help 
    } 
} 
+0

嘗試用這種'collectionView.collectionViewLayout.invalidateLayout()'也許可以幫助你 –

回答

0

嘗試通過flowLayout.invalidateLayout()

override func viewDidLayoutSubviews() { 
    super.viewDidLayoutSubviews() 

    print("\(view.bounds.width) x \(view.bounds.height)") 

    let boundsSize = CGSize(width: Int(view.bounds.width), height: Int(view.bounds.height)) 
    let flowLayout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout 

    if flowLayout.itemSize != boundsSize { 
     flowLayout.itemSize = boundsSize 

     debugPrint("Called") 
     flowLayout.invalidateLayout() 
    } 
} 

希望更換collectionView.layoutIfNeeded()這有助於

+0

'的invalidateLayout()'沒有做的伎倆,它給出了相同的結果 – Joey

+0

@Joey你確定你的代碼進入if?把一個debugPrint放在那裏,檢查 –

+0

是的,確實是 – Joey

0

您可以viewDidLayoutSubviews一起使用collectionView(_:layout:sizeForItemAt:)

override func viewDidLayoutSubviews() { 
    super.viewDidLayoutSubviews() 

    print("\(view.bounds.width) x \(view.bounds.height)") 

    let boundsSize = CGSize(width: Int(view.bounds.width), height: Int(view.bounds.height)) 

    if !boundsSize.equalTo(self. collectionViewItemSize) { 
     collectionView.invalidateLayout() 
    } 
} 

var collectionViewItemSize:CGSize = .zero 

func collectionView(_ collectionView: UICollectionView, 
        layout collectionViewLayout: UICollectionViewLayout, 
        sizeForItemAt indexPath: IndexPath) -> CGSize { 
    self.collectionViewItemSize = CGSize(width: Int(view.bounds.width), height: Int(view.bounds.height)); 
    return self.collectiViewItemSize; 
} 
+0

這給出了相同的結果。所以它首先重複調用'viewDidLayoutSubviews'然後調用'sizeForItemAt'並返回預期的大小。然後,佈局再次以相同的尺寸被調用,它被無效並且再次重複調用項目的大小(如果我取出檢查以確定實際尺寸已經改變),那麼佈局被稱爲第三次和第四次,但是它不是無效的它似乎是因爲它不會再次調用'sizeForItemAt'。 – Joey

+0

這不是問題,即使你完全比較它不能按預期工作。它會觸發'invalidateLayout()',但不會爲第三個和第四個佈局事件調用'sizeForItemAt'。 – Joey

+0

@Joey:奇怪。調用invalidateLayout後立即調用setLayout。這應該肯定會觸發sizeForItemAt方法。 –

相關問題