Вот проблема дизайна в приложении, использующая AutoLayout, UICollectionView и UICollectionViewCell, которая автоматически изменяет размер и высоту в зависимости от ограничений AutoLayout и его содержимого (некоторый текст).
Это список UITableView, например, с каждой ячейкой, которая имеет собственную ширину и высоту, вычисленную отдельно для каждой строки, зависящей от ее содержимого. Это больше похоже на создание iOS-сообщений в приложении (или WhatsUp).
Очевидно, что приложение должно использовать func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
.
Проблема заключается в том, что в этом методе приложение не может вызывать func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
и dequeueReusableCellWithReuseIdentifier(identifier: String, forIndexPath indexPath: NSIndexPath!) -> AnyObject
для создания экземпляра ячейки, заполнения ее конкретным контентом и вычисления его ширины и высоты. Попытка сделать это приведет к бессрочным вызовам рекурсии или к потере какого-либо другого типа (по крайней мере, в iOS 8.3).
Ближайший способ исправить эту ситуацию, похоже, скопирует определение ячейки в иерархию представлений, чтобы автоматическая компоновка автоматически изменяла размер ячейки (например, ячейка имела ту же ширину, что и представление родительской коллекции), поэтому приложение может конфигурировать ячейку с конкретный контент и рассчитать его размер. Это определенно не единственный способ исправить это из-за дублированных ресурсов.
Все это связано с настройкой UILabel.preferredMaxLayoutWidth на какое-то значение, которое должно быть автоматическим макетом (не жестко запрограммированным), который может зависеть от ширины и высоты экрана или, по крайней мере, с помощью определения ограничения автомакета, поэтому приложение может получить вычисляется многострочный внутренний размер UILabel.
Я бы не хотел создавать экземпляры ячеек из XIB файла, так как Storyboards должны быть сегодня отраслевым стандартом, и я хотел бы иметь меньшее вмешательство в код.
EDIT:
Базовый код, который не может быть запущен, приведен ниже. Таким образом, только экземпляр переменной cellProbe (не используется) приводит к сбою приложения. Без этого вызова приложение работает плавно.
var onceToken: dispatch_once_t = 0
class ViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
dispatch_once(&onceToken) {
let cellProbe = collectionView.dequeueReusableCellWithReuseIdentifier("first", forIndexPath: NSIndexPath(forRow: 0, inSection: 0)) as! UICollectionViewCell
}
return CGSize(width: 200,height: 50)
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("first", forIndexPath: NSIndexPath(forRow: 0, inSection: 0)) as! UICollectionViewCell
return cell
}
}