Swift4 - я не могу показать CollectionView в первый раз "Невозможно одновременно удовлетворить ограничения" - PullRequest
0 голосов
/ 14 ноября 2018

Я создаю приложение с помощью Swift 4, где я делаю запрос к API и хочу вернуть результат в CollectionView.

Но я получаю следующую ошибку, которая, я думаю, связана с ограничениями:

enter image description here

Этот блок повторяется 100 раз.

И в результате он не рисует никаких клеток. Показываю изображение вот так:

enter image description here

Если я не нажму верхнюю кнопку «ИЗМЕНИТЬ АВТОСПОЛОЖЕНИЕ» дважды. Это когда вы рисуете ячейки двух режимов отображения, которые у вас есть, и это выглядит так:

enter image description here

А это:

enter image description here

Но проблема в том, что изначально ничего не показывается и должно быть показано. И появляется ошибка, которую я показываю вам в начале.

Чтобы вам немного помочь, поскольку я бы сказал, что проблема возникает из-за примененного ограничения, я прилагаю несколько изображений с различными примененными ограничениями.

Исходная xib, где находится collectionView:

enter image description here

Первоначально загружена ячейка:

enter image description here

Ячейка, как только мы изменили макет, выглядит так:

enter image description here

Я прикрепил код основного класса, ViewVontroller, который управляет CollectionView:

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)

}
}

1 Ответ

0 голосов
/ 15 ноября 2018

Вы не устанавливаете UICollectionViewDelegateFlowLayout в viewController. Вам нужно установить его, а затем использовать

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

Чтобы установить размеры ваших клеток.

У вас ошибка, потому что при первой загрузке ячеек вы в основном говорите им, что они имеют размер 0 0.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...