ios - Swift4 - 我第一次无法显示 CollectionView "Unable to simultaneously satisfy constraints"

标签 ios swift uicollectionview constraints uicollectionviewflowlayout

我正在使用 Swift 4 创建一个应用程序,我在其中向 API 发出请求并希望在 CollectionView 上返回结果。

但我收到以下错误,我认为这是来自约束:

enter image description here

此 block 重复 100 次。

结果是他没有绘制任何单元格。显示这样的图像:

enter image description here

除非我按两次顶部按钮“CHANGE AUTOLAYOUT”。这是当你绘制你拥有的两种显示模式的单元格时,它看起来像这样:

enter image description here

还有这个:

enter image description here

但问题是,最初什么也没有显示,应该显示。并且出现了我在开始时向您展示的错误。

为了给您一点帮助,因为我会说问题是由应用的约束引起的,所以我附上了一些应用了不同约束的图像。

collectionView所在的初始xib是:

enter image description here

最初加载的单元格是:

enter image description here

我们改变布局后的单元格是这样的:

enter image description here

我附上了主类的代码,即控制 CollectionView 的 ViewVontroller:

import UIKit
import RxSwift
import RxCocoa

final class SpeedRunListViewController: UIViewController {

@IBOutlet private var collectionView: UICollectionView!
@IBOutlet private var buttonChangeLayout: UIButton!

private let disposeBag = DisposeBag()
private var viewModelList: SpeedRunListViewModel?
private var numElementsByCol: CGFloat = 3

override func viewDidLoad() {
    super.viewDidLoad()
    navigationController?.isNavigationBarHidden = true
    setupCollectionView()
    viewModelList = SpeedRunListViewModel(interactor: InteractorSpeedRunSearch())
    setupRx(viewModel: viewModelList!)
    viewModelList?.fetch()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    navigationController?.isNavigationBarHidden = true
}


private func setupCollectionView() {
    registerCollectionCells()
    if #available(iOS 10.0, *) {
        collectionView.isPrefetchingEnabled = false
    } else {
        // Fallback on earlier versions
    }
    calculateLayoutCollectionItem()
}


private func registerCollectionCells() {
    collectionView.register(UINib(nibName: SpeedRunRowCollectionViewCell.nibName, bundle: nil),
                            forCellWithReuseIdentifier: SpeedRunRowCollectionViewCell.reuseCellId)

    collectionView.register(UINib(nibName: SpeedRunCollectionViewCell.nibName, bundle: nil),
                            forCellWithReuseIdentifier: SpeedRunCollectionViewCell.reuseCellId)

}

private func calculateLayoutCollectionItem() {
    if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
        layout.estimatedItemSize = CGSize.init(width: 2, height: 2)
    }
}

private func setupRx(viewModel: SpeedRunListViewModel) {
    viewModel.numElements.asObservable().subscribe(onNext: { e in
        self.collectionView.reloadData()
    }, onError: { error in

    }, onCompleted: {

    }, onDisposed: {

    }).disposed(by: disposeBag)


    buttonChangeLayout.rx.tap.subscribe(onNext: { void in
        guard let value = self.viewModelList?.layoutRow else {
            return
        }
        self.viewModelList?.layoutRow = !value
        self.collectionView.collectionViewLayout.invalidateLayout()
        self.collectionView.reloadData()
    }, onError: { error in

    }, onCompleted: {

    }, onDisposed: {

    }).disposed(by: disposeBag)

}

fileprivate func getCellId() -> String {
    if let layoutRow = self.viewModelList?.layoutRow, layoutRow == true {
        return SpeedRunRowCollectionViewCell.reuseCellId
    }
    return SpeedRunCollectionViewCell.reuseCellId
}

}

//MARK: - UICollectionViewDelegate, UICollectionViewDataSource
extension SpeedRunListViewController: UICollectionViewDelegate, 
UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    guard let numElements = viewModelList?.numElements else {
        return 0
    }
    return numElements.value
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: getCellId(), for: indexPath) as! SpeedRunCollectionViewCellBase
    if let cellViewModel = viewModelList?.getCellViewModel(index: indexPath.row) {
        cell.setupCell(viewModel: cellViewModel)
    }

    return cell
}


func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    guard let speedRun = viewModelList?.getSpeedRun(index: indexPath.row) else {
        return
    }

    let interactorDetail: InteractorSpeedRunDetail = InteractorSpeedRunDetail(speedRun: speedRun)
    let viewControllerDetail: SpeedRunDetailViewController = SpeedRunDetailViewController(interactor: interactorDetail)
    viewControllerDetail.URISpeedRunDetail = (speedRun.links![1].uri)!

    navigationController?.pushViewController(viewControllerDetail, animated: true)
}


}

事实上,我不知道为什么会发生布局冲突。但这让我发疯......我不明白细胞最初是如何不显示的(因为正在接收数据)。会是什么?

非常感谢,任何问题都可以联系我。

[代码更新]

这些是代码解决方案:

//MARK: - UICollectionViewDelegateFlowLayout
extension SpeedRunListViewController: UICollectionViewDelegateFlowLayout {

func collectionView(_ collectionView: UICollectionView,
                    layout collectionViewLayout: UICollectionViewLayout,
                    sizeForItemAt indexPath: IndexPath) -> CGSize{


    if let value = self.viewModelList?.layoutRow {
        if value {
            return CGSize(width: 320, height: 144)
        }
        else{
            return CGSize(width: 96, height: 162)
        }
    }

    return CGSize(width: 320, height: 144)

}
}

最佳答案

您没有在 viewController 中设置 UICollectionViewDelegateFlowLayout。你需要设置它然后使用

func collectionView(_ collectionView: UICollectionView, 
                  layout collectionViewLayout: UICollectionViewLayout, 
           sizeForItemAt indexPath: IndexPath) -> CGSize

设置单元格的大小。

您遇到错误是因为当您第一次加载单元格时,您基本上是在告诉它们它们的大小为 0 0。

关于ios - Swift4 - 我第一次无法显示 CollectionView "Unable to simultaneously satisfy constraints",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53301245/

相关文章:

ios - 按下 TextField 时向上移动 UIView

ios - 推送通知不适用于具有 "completely unknown token"日志的特定设备

ios - 通过 App Delegate 从 UINavigationController 呈现 UIViewController

swift - 在 swift 中抓取 tableview 单元格中的 Url

swift - POD 安装出现问题 : "` ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES"

ios - 为什么 uicollectionview ui 更新不起作用

ios - UICollectionView header xib 未显示

iphone - Facebook-ios-sdk 对话框立即消失

ios - 是否可以增加 UICollectionViewLayout 视口(viewport)? (即在 UICollectionView 框架外加载 +2/-2 个单元格)