ios - UICollectionViewFlowLayout 问题
问题描述
提前道歉,但我这几天一直在绕圈子......
我有一个UIViewController
从另一个 VC 提供的(在我的例子中,点击了一个按钮)。新的 VC(代码如下)由以下部分组成:
- a
UITextView
根据用户输入的内容动态增加高度 - a
UIView
具有固定高度
然后在其下方,到 ViewController 视图的底部,是一个 UICollectionView。这有 5 个部分可以水平滚动。我将在这 5 个单元格中的每一个中插入不同的内容,但在 UICollectionView 调整大小时遇到问题。我已经能够清除其中的大多数,除了一个。
UITextView
每当大小增加到 3-6 行之间,并且再次增加到 13 行时,都会重现此错误...这发生在使用 iPhone 8 plus 的模拟器中,但在 iPhone 11 Pro Max 上,它只发生在 19 左右中的文本行UITextView
。
我在这里使用 TinyContraints,但我已经使用传统的编程约束进行了测试,并且遇到了同样的问题。
//
// NewItemVC.swift
//
import TinyConstraints
import UIKit
class NewItemVC: UIViewController {
let titleField = UITextView()
let bannerContainer = UIView(frame: .zero)
var flowLayout = UICollectionViewFlowLayout()
lazy var horizontalCV = UICollectionView(frame: .zero, collectionViewLayout: flowLayout)
let genericCellID = "genericCellID"
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .orange
setupHeaderArea()
setupBannerArea()
setupHorizontalCollectionView()
}
func setupHeaderArea(){
titleField.backgroundColor = .lightGray
titleField.textContainerInset.top = 55
titleField.textContainerInset.bottom = 20
titleField.textContainerInset.left = 15
titleField.textContainerInset.right = 15
titleField.font = UIFont.boldSystemFont(ofSize: 20)
// add to main view & position
view.addSubview(titleField)
titleField.topToSuperview()
titleField.leftToSuperview()
titleField.rightToSuperview()
titleField.isScrollEnabled = false
NotificationCenter.default.addObserver(self, selector: #selector(updateTextFieldHeight), name: UITextView.textDidChangeNotification, object: nil)
// add a header label
let headerLabel = UILabel()
headerLabel.textColor = .systemBlue
headerLabel.text = "NEW ITEM"
headerLabel.font = UIFont.systemFont(ofSize: 12)
view.addSubview(headerLabel)
headerLabel.topToSuperview(offset: 35)
headerLabel.leftToSuperview(offset: 20)
headerLabel.height(13)
// add card handle
let handle = UIView()
handle.backgroundColor = .black
handle.alpha = 0.2
handle.width(45)
handle.height(5)
handle.layer.cornerRadius = 5/2
view.addSubview(handle)
handle.topToSuperview(offset: 10)
handle.centerXToSuperview()
}
func setupBannerArea(){
// position container
view.addSubview(bannerContainer)
bannerContainer.topToBottom(of: titleField)
bannerContainer.edgesToSuperview(excluding: [.top, .bottom])
bannerContainer.height(62)
bannerContainer.backgroundColor = .cyan
}
func setupHorizontalCollectionView() {
horizontalCV = UICollectionView(frame: .zero, collectionViewLayout: flowLayout)
horizontalCV.dataSource = self
horizontalCV.delegate = self
horizontalCV.backgroundColor = .yellow
horizontalCV.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
horizontalCV.scrollIndicatorInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
view.addSubview(horizontalCV)
horizontalCV.topToBottom(of: bannerContainer)
horizontalCV.edgesToSuperview(excluding: .top)
horizontalCV.isPagingEnabled = true
horizontalCV.contentInsetAdjustmentBehavior = .never
flowLayout.scrollDirection = .horizontal
flowLayout.minimumLineSpacing = 0
flowLayout.minimumInteritemSpacing = 0
horizontalCV.register(UICollectionViewCell.self, forCellWithReuseIdentifier: genericCellID)
}
@objc func updateTextFieldHeight() {
DispatchQueue.main.async{
self.horizontalCV.collectionViewLayout.invalidateLayout()
}
}
}
// MARK:- Delegates - UITextViewDelegate
extension NewItemVC: UITextViewDelegate {
func textViewDidChange(_ textView: UITextView) {
let size = CGSize(width: textView.frame.width, height: .infinity)
let estimatedSize = textView.sizeThatFits(size)
textView.constraints.forEach { (constraint) in
if constraint.firstAttribute == .height {
constraint.constant = estimatedSize.height
}
}
}
}
// MARK:- UICollectionView Data Source
extension NewItemVC: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: genericCellID, for: indexPath)
if indexPath.row % 2 == 0 {
cell.backgroundColor = .orange
} else {
cell.backgroundColor = .red
}
return cell
}
}
// MARK:- Delegates - UICollectionView Flow Layout
extension NewItemVC: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let requiredHeight = self.view.frame.height - (titleField.frame.height + bannerContainer.frame.height)
let requiredWidth = view.frame.width
return CGSize(width: requiredWidth, height: requiredHeight)
}
}
据我所知,collectionView 框架和 contentSize 随机出现一些问题,但我无法弄清楚为什么/在哪里等...
错误如下:
2020-02-06 20:39:18.425280+1100 Scrolling[67237:8005204] The behavior of the UICollectionViewFlowLayout is not defined because:
2020-02-06 20:39:18.425378+1100 Scrolling[67237:8005204] the item height must be less than the height of the UICollectionView minus the section insets top and bottom values, minus the content insets top and bottom values.
2020-02-06 20:39:18.425672+1100 Scrolling[67237:8005204] The relevant UICollectionViewFlowLayout instance is <UICollectionViewFlowLayout: 0x7fcf56d4a120>, and it is attached to <UICollectionView: 0x7fcf5785d000; frame = (0 208.667; 414 487.333); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x600000ce8a50>; layer = <CALayer: 0x600000213a00>; contentOffset: {0, 0}; contentSize: {2070, 511}; adjustedContentInset: {0, 0, 0, 0}; layout: <UICollectionViewFlowLayout: 0x7fcf56d4a120>; dataSource: <Scrolling.NewItemVC: 0x7fcf56d20110>>.
2020-02-06 20:39:18.425760+1100 Scrolling[67237:8005204] Make a symbolic breakpoint at UICollectionViewFlowLayoutBreakForInvalidSizes to catch this in the debugger.
解决方案
推荐阅读
- ruby-on-rails - Rails ActiveSupport::TestCase - 如何动态定义测试及其帮助方法?
- python - 用石灰 R 包解释我的 keras 对象的功能
- arrays - 您如何从 MIPS 中的数组制作水平条形图
- powerbi - 如何按特定列值添加自定义索引?
- mysql - Mysql获取只出现一次的值
- vba - 选择某些输入字段时使表单可见
- c# - 使用 log4net 为整个代码块中的每个日志附加一个值
- mysql - 使用开始和结束日期列过滤所有数据
- fortran - Fortran 2008 中使用非多态过程重载延迟过程
- ios - 拦截 WKWebView 进行 pdf 下载