[英]Horizontal paging UICollectionView with automatic item size in a vertical stack view?
[英]UICollectionView crashes when item size is automatic and header is shown
當我想將 UICollectionView 的estimatedItemSize
屬性設置為UICollectionView
並同時顯示UICollectionViewFlowLayout.automaticSize
部分時,我遇到了一個奇怪的錯誤。
使用以下代碼,應用程序可以正確顯示UICollectionView
。 但是,一旦用戶在UICollectionView
上滾動,應用程序會因遞歸調用 function updateVisibleCellsNow
而崩潰。
我通過將estimatedItemSize
從automaticSize
設置為none
從另一個 StackOverflow 問題中找到了解決方法。 但是,我想保留在UICollectionViewCell
中設置的自動布局功能,而不是自己計算單元格高度。 有沒有更好的解決方案? 謝謝你。
這是我關於 ViewController 的代碼
import UIKit
class DemoCollectionViewController: UIViewController {
lazy private var collectionView: UICollectionView = { [weak self] in
guard let strongSelf = self else { return UICollectionView() }
// Setup of `UICollectionViewFlowLayout`
let flowLayout = UICollectionViewFlowLayout()
// ********* This is the line that causes crash *********
flowLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
// ******************************************************
flowLayout.headerReferenceSize = CGSize(width: getScreenWidth(), height: 44.0)
flowLayout.sectionHeadersPinToVisibleBounds = true
// Setup of `UICollectionView`
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: flowLayout).disableFrameToAutoLayout()
collectionView.dataSource = strongSelf
collectionView.register(ProfileThumbnailCollectionViewCell.self, forCellWithReuseIdentifier: "cellId")
collectionView.register(UICollectionReusableView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "headerId")
return collectionView
}()
override func viewDidLoad() {
super.viewDidLoad()
// Setup of the UICollectionView
view.addSubview(collectionView)
NSLayoutConstraint.activate([
collectionView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
collectionView.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor),
collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
collectionView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor),
])
}
}
extension DemoCollectionViewController: UICollectionViewDataSource {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 20
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! ProfileThumbnailCollectionViewCell
cell.contentView.backgroundColor = .yellow
return cell
}
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionView.elementKindSectionHeader:
let supplementaryView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "headerId", for: indexPath)
supplementaryView.backgroundColor = .red
return supplementaryView
default:
return UICollectionReusableView()
}
}
}
這是我關於ProfileThumbnailCollectionViewCell
的代碼:
class ProfileThumbnailCollectionViewCell: UICollectionViewCell {
private let profileThumbnailImageView: UIImageView = {
let profileThumbnailImageView = UIImageView()
profileThumbnailImageView.translatesAutoresizingMaskIntoConstraints = false
profileThumbnailImageView.backgroundColor = .red
profileThumbnailImageView.layer.cornerRadius = 60
profileThumbnailImageView.layer.masksToBounds = true
return profileThumbnailImageView
}()
private let editPenButton: UIButton = {
let editPenButton = UIButton()
editPenButton.translatesAutoresizingMaskIntoConstraints = false
editPenButton.backgroundColor = .mainGreen
editPenButton.layer.cornerRadius = 16
editPenButton.layer.masksToBounds = true
return editPenButton
}()
override init(frame: CGRect) {
super.init(frame: frame)
// Content View
contentView.backgroundColor = .yellow
NSLayoutConstraint.activate([
contentView.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width)
])
// Profile Thumbnail ImageView
contentView.addSubview(profileThumbnailImageView)
NSLayoutConstraint.activate([
profileThumbnailImageView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
profileThumbnailImageView.widthAnchor.constraint(equalToConstant: 120),
profileThumbnailImageView.heightAnchor.constraint(equalToConstant: 120),
profileThumbnailImageView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 25),
profileThumbnailImageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -25)
])
// Edit thumbnail pen ImageView
contentView.addSubview(editPenButton)
NSLayoutConstraint.activate([
editPenButton.widthAnchor.constraint(equalToConstant: 32),
editPenButton.heightAnchor.constraint(equalToConstant: 32),
editPenButton.rightAnchor.constraint(equalTo: contentView.rightAnchor),
editPenButton.rightAnchor.constraint(equalTo: contentView.rightAnchor)
])
}
required init?(coder: NSCoder) {
fatalError("This class should be inited from code instead of a nib file; init(coder:) has not been implemented")
}
}
在 ViewDidLoad 中調用 registerNib
func registerNib(){
let nib = UINib(nibName: "ProfileThumbnailCollectionViewCell", bundle: nil)
self.collectionView.register(nib, forCellWithReuseIdentifier: "ProfileThumbnailCollectionViewCell")
}
在調查了幾個小時后,我無意中找到了一個變通的解決方案,但肯定這不應該被視為最終解決方案。
class ProfileThumbnailCollectionViewCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
// Content View
contentView.backgroundColor = .yellow
// ******** This is the weird point ********
let targetCellWidth = UIScreen.main.bounds.width - 1
NSLayoutConstraint.activate([
contentView.widthAnchor.constraint(equalToConstant: targetCellWidth)
])
}
}
UICollectionView
不會拋出任何錯誤,並正確顯示 header 視圖和UICollectionView
。
如果您對這種情況有任何想法,請在此處留下您的評論。 非常感謝您的信息! 謝謝!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.