我需要根据不同的条件调整我的集合视图单元格的大小。
这就是我现在用的:
class CustomTabView: UIView {
...
func collectionView(
_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath
) -> CGSize {
calculateNeededItemSize()
}
func calculateNeededItemSize() -> CGSize {
if tabsList.count > Constant.maximumFullscreenTabsCount {
return UICollectionViewFlowLayout.automaticSize
} else {
return CGSize(width: determineItemWidthForFullscreen(), height: frame.height)
}
}
func determineItemWidthForFullscreen() -> CGFloat {
return UIScreen.main.bounds.width / CGFloat(tabsList.count)
}
当我用一些测试块指定这行代码“return UICollectionViewFlowLayout.automaticSize”时,它工作正常。但否则我会得到一个致命错误:
Thread 1: "UICollectionViewLayoutAttributes: -setFrame: requires finite coordinates <UICollectionViewLayoutAttributes: 0x138d079e0; index path: (0-0); frame = (0 0; 0 0)> - {{0, -inf}, {1.7976931348623157e+308, 1.7976931348623157e+308}}"
另外,当我指出这一行时 'layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize' 没有方法
sizeForItemAt
它可以工作,但我只需要我的细胞根据条件有不同的大小。
集合视图单元格包含一个标签,其宽度应根据文本行进行调整:
private lazy var titleLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 1
label.textAlignment = .center
label.textColor = .white
label.font = UIFont.systemFont(ofSize: Constant.titleFontSize, weight: .medium)
return label
}()
func setupView() {
contentView.addSubview(titleLabel)
NSLayoutConstraint.activate([
titleLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor,constant: 15),
titleLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor,constant: -15),
titleLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor)
])
}
我建议使用 Compositional Layouts 而不是您正在使用的 FlowLayout。 FlowLayout 需要计算集合视图中每个单元格的精确大小,而 Compositional Layout 可以在单元格受到适当约束的情况下计算最佳拟合大小。此外,您可以在项目中采用Composure库来进一步简化组合布局的实现。如果您实现推荐的库,您的实现将如下所示:
import UIKit
import Composure
enum LayoutSections: Int, CaseIterable, DefinesCompositionalLayout {
//list the number of sections in your layout. in this example there are 2 sections with
//different layout requirements
case section1
case section2
func layoutInfo(using layoutEnvironment: NSCollectionLayoutEnvironment) -> CompositionalLayoutOption {
switch self {
case .section1:
//estimatedHeight does not need to be precise
return .fullWidthDynamicHeight(estimatedHeight: 120)
case .section2:
return .fixedWidthDynamicHeight(fixedWidth: 180, estimatedHeight: 150)
}
}
}
然后在视图控制器中,您将执行此操作来执行布局。冷静会照顾到其余的事情。
import UIKit
import Composure
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//other code
collectionView.collectionViewLayout = generateCompositionalLayout(with: LayoutSections.allCases)
//...
}
...
}