Ячейки CollectionView не имеют правильного размера - PullRequest
0 голосов
/ 09 июля 2020

Я создал представление коллекции с ячейками, которые предназначены только для отображения изображения и заголовка под ним. Все появляется прямо в конструкторе интерфейсов и с ограничениями. Когда представление фактически загружается, все изображение не загружается и обрезается, как вы можете видеть на изображениях ниже. Я бы хотел, чтобы размер ячеек составлял x-ю часть экрана (скажем, треть ширины экрана для простоты)?

NewsController

class NewsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
    
    private static let headlineArticleReuseIdentifier = "HeadlineArticleCell"
    private static let categoryCellReuseIdentifier = "NewsCategoryCell"
    
    @IBOutlet weak var categoriesList: UICollectionView!
    @IBOutlet weak var categoriesFlowLayout: UICollectionViewFlowLayout!
    @IBOutlet weak var headlineArticlesPreviewList: UITableView!
    private var bindings = Set<AnyCancellable>()
    private var viewModel: NewsViewModel = NewsViewModel()
    private var headlineArticles: [Article] = []
    private var categories: [Category] = []
    
    @IBOutlet weak var headlineTitle: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        view.isSkeletonable = true
        view.showGradientSkeleton()
        headlineArticlesPreviewList.delegate = self
        headlineArticlesPreviewList.dataSource = self
        categoriesList.dataSource = self
        categoriesList.delegate = self
        
        let cancellable = viewModel.$viewState.sink(receiveValue: { state in
            switch state {
            case let .data(data):
                self.setData(data: data)
                print()
            case let .error(error):
                print(error)
            case .loading:
                self.headlineTitle.showGradientSkeleton()
                self.headlineArticlesPreviewList.showGradientSkeleton()
                print()
            }
        })
        bindings.insert(cancellable)
    }
    
    private func setData(data: NewsViewModel.ViewState.Data) {
        self.view.hideSkeleton()
        self.headlineArticles = data.headlineArticles
        self.headlineTitle.text = data.headlineCategory.displayName
        self.headlineArticlesPreviewList.reloadData()
        self.categories = data.categories
        self.categoriesList.reloadData()
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if (tableView == headlineArticlesPreviewList) {
            return headlineArticles.count
        } else {
            return 0
        }
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = headlineArticlesPreviewList.dequeueReusableCell(
            withIdentifier: NewsViewController.headlineArticleReuseIdentifier,
            for: indexPath)
            as? HeadlineArticleTableViewCell else {
                fatalError("could not cast to headline article")
        }
        let headlineArticle = headlineArticles[indexPath.item]
        cell.setArticle(article: headlineArticle)
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        self.categories.count
    }
    
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        1
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = categoriesList.dequeueReusableCell(withReuseIdentifier: NewsViewController.categoryCellReuseIdentifier, for: indexPath) as? NewsCategoryCollectionViewCell else {
            fatalError("could not cast to news category")
        }
        let newsCategory = categories[indexPath.item]
        cell.setCategory(category: newsCategory)
        cell.isInteractable = true
        cell.cornerRadius = 8
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        let noOfCellsInRow = 3

        let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout

        let totalSpace = flowLayout.sectionInset.left
            + flowLayout.sectionInset.right
            + (flowLayout.minimumInteritemSpacing * CGFloat(noOfCellsInRow - 1))

        let size = Int((collectionView.bounds.width - totalSpace) / CGFloat(noOfCellsInRow))

        return CGSize(width: size, height: size)
    }

}


Ограничения

Constraints Cell Image

Cell Image

Cell Size

enter image description here

What happens Что случается

Ответы [ 2 ]

1 голос
/ 09 июля 2020

Добавьте UICollectionViewDelegateFlowLayout в свой код.

Swift

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: UIScreen.main.bounds.size.width * 0.4,height: UIScreen.main.bounds.size.width * 0.4)
    }

цель c

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
    
    return  CGSizeMake([[UIScreen mainScreen] bounds].size.width * 0.4, [[UIScreen mainScreen] bounds].size.height * 0.4);
}
0 голосов
/ 09 июля 2020

Установлено ли для вашего вида коллекции автоматическое изменение размера? Похоже, он использует размеры элементов по умолчанию для представления коллекции. Вы можете узнать больше о том, как реализовать саморазмер collectionView здесь

Еще одно предложение, если вы используете фиксированное соотношение сторон: 1: 1 и ширина imageView равна 144, просто установите высоту ограничение как 144 и удалите соотношение сторон.

Третье предложение, посмотрите на консоль, есть ли ошибки LayoutConstraint? Если это так, вероятно, он не может создать соотношение сторон 1: 1 и нарушает ограничение. Вы можете попробовать снизить приоритет соотношения сторон до 750, обычно это помогает в такой ситуации, если нет, посмотрите на первые два предложения.

Кроме того, я вижу, что ваша метка также имеет фиксированную высоту, 25, так что технически ваша ячейка 144 * (144 + 25), поэтому вы можете установить для своего itemSize эти значения и вообще не использовать самостоятельную калибровку.

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