Невозможно установить ширину UICollectionViewCell с AutoLayout - PullRequest
0 голосов
/ 18 сентября 2018

У меня есть коллекционное представление с ячейками динамической высоты (на основе, возможно, многострочной метки и текстового представления внутри), которое идеально адаптируется по высоте, когда я разбиваю его на несколько строк. Однако, когда текст представляет собой всего одно слово или не охватывает всю ширину экрана, ячейка становится настолько широкой, насколько это необходимо, в результате чего ячейки располагаются рядом друг с другом, а не под друг другом.

Посмотрите на результат с различной длиной текста внутри textview.

Тем не менее, я хочу, чтобы ячейки находились друг под другом, как в Instagram или Twitter. Очевидно, мне нужно установить ограничение ширины для ячейки, чтобы оно равнялось всей ширине экрана, но я не могу найти, как это сделать.

Я использую FlowLayout с предполагаемым размером элемента в моем AppDelegate:

let layout = UICollectionViewFlowLayout()
window?.rootViewController = UINavigationController(rootViewController: HomeController(collectionViewLayout: layout))

layout.estimatedItemSize = CGSize(width: 414, height: 150)

Я также установил ограничения для collectionView в viewDidLoad, поэтому collectionView принимает всю ширину и высоту экрана:

collectionView?.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
collectionView?.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
collectionView?.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
collectionView?.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true

Мои ограничения для метки и вида текста выглядят так, что позволяет ширине принимать требуемый размер (поэтому он не фиксирован):

// vertical constraints usernameLabel & commentTextView
addConstraintsWithFormat(format: "V:|-16-[v0]-2-[v1]-16-|", views: usernameLabel, commentTextView)

// horizontal constraints usernameLabel
addConstraintsWithFormat(format: "H:|-16-[v0]-16-|", views: usernameLabel)

// horizontal constraints commentTextView
addConstraintsWithFormat(format: "H:|-16-[v0]-16-|", views: commentTextView)

Все это, по моему мнению, необходимо для этой работы. Тем не менее, мне кажется, что я еще не установил ограничение ширины, чтобы сделать эту работу. Я попытался добавить widthAnchor на collectionView (равно view.widthAnchor), это не сработало:

collectionView?.widthAnchor.constraint(equalTo: self.view.widthAnchor).isActive = true

Я также попытался установить ширину в методе sizeForItemAt, но это также не сработало:

return CGSize(width: view.frame.width, height: 100)

Теперь я проверяю ширину, чтобы увидеть, где она идет не так, но я получаю результат, который мне нужен, я думаю:

print("collectionView width: ", collectionView?.frame.size.width)
print("collectionView height: ", collectionView?.frame.size.height)

print("screen width: ", UIScreen.main.bounds.width)
print("screen height: ", UIScreen.main.bounds.height)

Результаты:

collectionView width:  Optional(414.0)
collectionView height:  Optional(736.0)
screen width:  414.0
screen height:  736.0

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

Есть идеи, что я делаю не так?

Ответы [ 2 ]

0 голосов
/ 18 сентября 2018

Обновление:

Я добавил расширение для моего HomeController согласно ответу Siju Satheesachandran:

extension HomeController {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: 400, height: 100)
    }
}

Затем в методе cellForItemAt ядобавлен отпечаток для ширины текущей ячейки:

print("cell width: ", cell.frame.size.width)

, который в пять раз возвращает следующее:

cell width:  400.0

Так что, на мой взгляд, требуемый размер прослушивается, но мойЯчейка просто адаптируется к любой ширине, которую она хочет?

Еще одно интересное обновление:

Когда я изменяю текст моего TextView на что-то слишком длинное, поэтому оно должноразбить на несколько строк, и я запускаю приложение, приложение выдает эту ошибку отладки бесконечное количество раз, не загружая и не отображая черный экран:

2018-09-18 15:34:35.806688+0200 prjDynamicCells[39793:1627318] The behavior of the UICollectionViewFlowLayout is not defined because:
2018-09-18 15:34:35.807472+0200 prjDynamicCells[39793:1627318] the item width must be less than the width of the UICollectionView minus the section insets left and right values, minus the content insets left and right values.
2018-09-18 15:34:35.807572+0200 prjDynamicCells[39793:1627318] Please check the values returned by the delegate.
2018-09-18 15:34:35.807911+0200 prjDynamicCells[39793:1627318] The relevant UICollectionViewFlowLayout instance is <UICollectionViewFlowLayout: 0x7feb5ec17650>, and it is attached to <UICollectionView: 0x7feb5f841600; frame = (0 0; 414 736); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x60000044e6d0>; layer = <CALayer: 0x60000003f4a0>; contentOffset: {0, -64}; contentSize: {414, 1000}; adjustedContentInset: {64, 0, 0, 0}> collection view layout: <UICollectionViewFlowLayout: 0x7feb5ec17650>.
2018-09-18 15:34:35.808009+0200 prjDynamicCells[39793:1627318] Make a symbolic breakpoint at UICollectionViewFlowLayoutBreakForInvalidSizes to catch this in the debugger.
0 голосов
/ 18 сентября 2018

Обязательно добавьте этот протокол в приложение

UICollectionViewDelegate
UICollectionViewDataSource
UICollectionViewDelegateFlowLayout

Пожалуйста, используйте ниже метод

    extension YourViewController: UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {

        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
             return CGSize(width: screenWidth, height: screenWidth)
        }

    }
...