Использование swift-5.0.1, iOS-12.2,
Я наблюдаю странное поведение на UICollectionView:
Внутри моего collectionView есть ячейки на весь экран, на которых показано изображение.
Мое наблюдение состоит в том, что всякий раз, когда изображение не может быть получено - в таком случае, вышеуказанная ячейка оказывается больше по размеру, чем ожидалось. Вопрос почему ??
Следующее изображение иллюстрирует проблему:
Любое изображение, которое нельзя получить, очевидно, не может быть отображено, и его ячейка получает backgroundColer, равный красному. Это все работает. Но почему одна ячейка, которая находится прямо над нулевой ячейкой, увеличилась в размерах ???
Все ячейки должны иметь размер, указанный желтыми прямоугольниками.
У меня есть два места в моем коде, где затрагивается высота ячейки:
- внутри инициализатора UICollectionViewCell:
mainImageView.heightAnchor.constraint(equalToConstant: 150)
- внутри UICollectionViewController
sizeForItemAt
:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return .init(width: view.frame.width, height: 150)
}
Оба установлены на 150! Но в случае ошибки большая ячейка больше 150 - почему ??
Вот код более подробно:
import UIKit
class PhotoListCollectionViewCell: UICollectionViewCell {
var mainImageView: UIImageView = {
let imgV = UIImageView()
imgV.contentMode = .scaleAspectFill
return imgV
}()
var dateLabel = UILabel()
var descriptionLabel = UILabel()
var nameLabel = UILabel()
var descContainerHeightConstraint = NSLayoutConstraint()
var photoListCellViewModel : PhotoListCellViewModel? {
didSet {
nameLabel.text = photoListCellViewModel?.titleText
descriptionLabel.text = photoListCellViewModel?.descText
mainImageView.sd_setImage(with: URL( string: photoListCellViewModel?.imageUrl ?? "" ), completed: nil)
dateLabel.text = photoListCellViewModel?.dateText
}
}
func setConstraints() {
addSubview(mainImageView)
mainImageView.translatesAutoresizingMaskIntoConstraints = false
mainImageView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
mainImageView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
mainImageView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
mainImageView.heightAnchor.constraint(equalToConstant: 150)
}
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = .red
self.setConstraints()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class CollectionViewController: BaseListController, UICollectionViewDelegateFlowLayout {
fileprivate let cellId = "cellId"
lazy var viewModel: PhotoListViewModel = {
return PhotoListViewModel()
}()
override func viewDidLoad() {
super.viewDidLoad()
initView()
initVM()
}
func initView() {
self.navigationItem.title = "NavBar"
collectionView.register(PhotoListCollectionViewCell.self, forCellWithReuseIdentifier: cellId)
collectionView.backgroundColor = .white
}
func initVM() { ... }
func showAlert( _ message: String ) { ... }
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return viewModel.numberOfCells
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as? PhotoListCollectionViewCell else {
fatalError("Cell could not be dequeued")
}
let cellVM = viewModel.getCellViewModel( at: indexPath )
cell.photoListCellViewModel = cellVM
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return .init(width: view.frame.width, height: 150)
}
}
Приведенный ниже код, скорее всего, не имеет отношения к вопросу (но по причинам полноты ...)
class BaseListController: UICollectionViewController {
init() {
super.init(collectionViewLayout: UICollectionViewFlowLayout())
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Я также пытался изменить imgV.contentMode = .scaleAspectFill
на imgV.contentMode = .scaleAspectFit
. Но затем я теряю полную ширину изображений, как показано на иллюстрации здесь:
Но я думаю, что все ближе. Какая может быть идеальная настройка?