Largura e altura variáveis do UICollectionViewCell usando o AutoLayout com Storyboard (sem XIB)
Aqui está um problema de design no aplicativo que usa AutoLayout, UICollectionView e UICollectionViewCell que possui largura e altura redimensionáveis automaticamente, dependendo das restrições do AutoLayout e de seu conteúdo (algum texto).
É uma lista do UITableView, com cada célula que possui sua própria largura e altura calculada separadamente para cada linha, dependendo do seu conteúdo. É mais como as mensagens do iOS construídas no aplicativo (ou WhatsUp).
É óbvio que o aplicativo deve fazer uso defunc collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize
.
O problema é que, dentro desse método, o aplicativo não pode chamarfunc collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
nemdequeueReusableCellWithReuseIdentifier(identifier: String, forIndexPath indexPath: NSIndexPath!) -> AnyObject
para instanciar uma célula, preencha-a com conteúdo específico e calcule sua largura e altura. Tentar fazer isso resultará em chamadas de recursão indefinidas ou em algum outro tipo de falha do aplicativo (pelo menos no iOS 8.3).
A maneira mais próxima de corrigir essa situação parece copiar a definição da célula na hierarquia da visualização para permitir que o Auto-layout redimensione automaticamente a "célula" (como a célula para ter a mesma largura que a exibição da coleção pai), para que o aplicativo possa configurar a célula com conteúdo específico e calcule seu tamanho. Definitivamente, essa não deve ser a única maneira de corrigi-lo devido a recursos duplicados.
Tudo isso está conectado à configuração de UILabel.preferredMaxLayoutWidth para algum valor que deve ser controlado pelo Layout automático (não codificado) que pode depender da largura e altura da tela ou, pelo menos, configurado pela definição de restrição de layout automático, para que o aplicativo possa obter o UILabel multilíngue intrínseco tamanho calculado.
Eu não gostaria de instanciar células do arquivo XIB, uma vez que os Storyboards deveriam ser o padrão da indústria atual e eu gostaria de ter menos intervenção no código.
EDITAR:
O código básico que não pode ser executado está listado abaixo. Portanto, apenas instanciar a variável cellProbe (não usada) trava o aplicativo. Sem essa ligação, o aplicativo funciona sem problemas.
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
}
}