Na vertical UICollectionView
,
É possível ter células de largura total , mas permitir que a altura dinâmica seja controlada pelo autolayout ?
Isso me parece talvez a "questão mais importante no iOS sem nenhuma resposta realmente boa."
Importante:
Observe que em 99% dos casos, para obter células de largura total + altura dinâmica de layout automático, basta usar uma visualização de tabela. É tão fácil.
Então, qual é um exemplo de onde você precisa de uma visualização de coleção?
As visualizações de coleção são incrivelmente mais poderosas do que as visualizações de tabela.
Um exemplo simples em que você realmente precisa usar uma visualização de coleção para obter células de largura total + altura dinâmica de layout automático:
Se você animar entre dois layouts em uma visualização de coleção. Por exemplo, entre um layout de 1 e 2 colunas, quando o dispositivo gira.
Esse é um idioma comum e normal no iOS. Infelizmente, isso só pode ser alcançado resolvendo o problema apresentado neste controle de qualidade. : - /
fonte
SpringDamping
einitialSpringVelocity
) na célula da tabela ..... dê uma olhada nesta Lista Bouncy usando tableView ,,,, pastebin.com/pFRQhkrX você pode animar aTableViewCell
tabela nowillDisplayCell:(UITableViewCell *)cell
método delgate @Fattie você pode aceitar a resposta que resolveu seu problema para ajudar outra pessoa que está procurando pelo mesmo problemaRespostas:
1. Solução para iOS 13+
Com o Swift 5.1 e iOS 13, você pode usar objetos de Layout Composicional para resolver seu problema.
O código de amostra completo a seguir mostra como exibir multilinhas
UILabel
em largura totalUICollectionViewCell
:CollectionViewController.swift
HeaderView.swift
CustomCell.swift
Exibição esperada:
2. Solução para iOS 11+
Com o Swift 5.1 e iOS 11, você pode
UICollectionViewFlowLayout
criar uma subclasse e definir suaestimatedItemSize
propriedade comoUICollectionViewFlowLayout.automaticSize
(isso informa ao sistema que você deseja lidar com o dimensionamento automáticoUICollectionViewCell
). Você terá que substituirlayoutAttributesForElements(in:)
elayoutAttributesForItem(at:)
para definir a largura das células. Por último, você terá que substituir opreferredLayoutAttributesFitting(_:)
método de sua célula e calcular sua altura.O código completo a seguir mostra como exibir multilinhas
UILabel
em largura totalUIcollectionViewCell
(restrito pelaUICollectionView
área segura de eUICollectionViewFlowLayout
inserções de):CollectionViewController.swift
CustomFlowLayout.swift
HeaderView.swift
CustomCell.swift
Aqui estão algumas implementações alternativas para
preferredLayoutAttributesFitting(_:)
:Exibição esperada:
fonte
Problema
Você está procurando altura automática e também quer ter largura total, não é possível obter os dois usando
UICollectionViewFlowLayoutAutomaticSize
.Você deseja fazer usando
UICollectionView
isso abaixo é a solução para você.Solução
1. Se você tiver apenas
UILabel
noCollectionViewCell
que defina onumberOfLines=0
e que calculou a altura esperada deUIlable
, passar todos os três o paramters2. Se você
CollectionViewCell
contém apenasUIImageView
e deve ser dinâmico em altura, você precisa obter a altura deUIImage
(vocêUIImageView
deve terAspectRatio
restrições)3. Se contiver ambos, calcule sua altura e some-os.
1. Adicionar
UICollectionViewDelegateFlowLayout
delegado em seu viewController2. Implementar o método delegado
Eu espero que isso te ajude.
fonte
return CGSize(width: view.frame.width/2, height: expectedHeight)
também mantenha o Padding em conta e retorne a largura, caso contrário duas células não caberiam em uma única linha.Existem algumas maneiras de resolver esse problema.
Uma maneira é dar ao layout do fluxo de visualização da coleção um tamanho estimado e calcular o tamanho da célula.
Observação: conforme mencionado nos comentários abaixo, a partir do iOS 10 você não precisa mais fornecer um tamanho estimado para acionar a chamada para uma célula
func preferredLayoutAttributesFitting(_ layoutAttributes:)
. Anteriormente (iOS 9), seria necessário fornecer um tamanho estimado se você quisesse consultar as células prefferedLayoutAttributes.(supondo que você esteja usando storyboards e a visualização da coleção esteja conectada via IB)
Para células simples, isso geralmente será o suficiente. Se o tamanho ainda estiver incorreto, você pode sobrescrever na célula de visualização da coleçãofunc preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes
, o que lhe dará mais controle de granulação fina sobre o tamanho da célula. Observação: você ainda precisará fornecer ao layout do fluxo um tamanho estimado .Em seguida, substitua
func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes
para retornar o tamanho correto.Alternativamente, você pode usar uma célula de dimensionamento para calcular o tamanho da célula no
UICollectionViewDelegateFlowLayout
.Embora esses não sejam exemplos perfeitos de produção, eles devem ajudar você a começar na direção certa. Não posso dizer que essa seja a melhor prática, mas funciona para mim, mesmo com células bastante complexas contendo vários rótulos, que podem ou não quebrar em várias linhas.
fonte
preferredLayoutAttributesFitting
. Em seguida, adicionei uma restrição minha na dita função, vinculando à dimensão fixa de estimadoItemSize, FWIW, veja minha resposta abaixo.Eu encontrei uma solução muito fácil para esse problema: dentro de meu CollectionViewCell eu tenho um UIView () que é na verdade apenas um plano de fundo. Para obter a largura total, basta definir as seguintes âncoras
A "mágica" acontece na primeira linha. Eu defino o widthAnchor dinamicamente para a largura da tela. Também é importante subtrair as inserções de seu CollectionView. Caso contrário, o celular não aparecerá. Se você não quiser ter essa visão de plano de fundo, basta torná-la invisível.
O FlowLayout usa as seguintes configurações
O resultado é uma célula de largura total com altura dinâmica.
fonte
TRABALHANDO!!! Testado em IOS: 12.1 Swift 4.1
Eu tenho uma solução muito simples que funciona sem quebrar as restrições.
Minha ViewControllerClass
Classe CustomCell:
Ingrediente principal é o systemLayoutSizeFitting função em Customcell. E também temos que definir a largura da visualização dentro da célula com restrições.
fonte
Você deve adicionar uma restrição de largura a CollectionViewCell
fonte
Conjunto
estimatedItemSize
do seu layout de fluxo:Defina uma restrição de largura na célula e defina-a para ser igual à largura da visualização:
Exemplo completo
Testado em iOS 11.
fonte
Pessoalmente, descobri que as melhores maneiras de ter um UICollectionView onde o AutoLayout determina o tamanho enquanto cada Cell pode ter um tamanho diferente é implementar a função UICollectionViewDelegateFlowLayout sizeForItemAtIndexPath enquanto usa uma Cell real para medir o tamanho.
Falei sobre isso em um de meus posts
Esperançosamente, este o ajudará a alcançar o que deseja. Não tenho 100% de certeza, mas acredito que ao contrário de UITableView, onde você pode realmente ter uma altura totalmente automática de células usando AutoLayout em conjunto com
UICollectionView não permite que o AutoLayout determine o tamanho, porque UICollectionViewCell não preenche necessariamente toda a largura da tela.
Mas aqui vai uma pergunta para você : se você precisa de células com largura de tela inteira, por que você se incomoda em usar o UICollectionView em vez de um bom e velho UITableView que vem com células de dimensionamento automático?
fonte
Por meu comentário sobre a resposta de Eric, minha solução é muito semelhante à dele, mas tive que adicionar uma restrição em preferredSizeFor ... para restringir à dimensão fixa.
Esta pergunta tem várias duplicatas, respondi em detalhes aqui e forneci um aplicativo de amostra funcional aqui.
fonte
Não tenho certeza se isso se qualifica como uma "resposta realmente boa", mas é o que estou usando para fazer isso. Meu layout de fluxo é horizontal e estou tentando fazer o ajuste de largura com autolayout, então é semelhante à sua situação.
Em seguida, no controlador de visualização em que a restrição autolayout é modificada, eu disparo um NSNotification.
Em minha subclasse UICollectionView, eu escuto essa notificação:
e invalidar o layout:
Isso faz
sizeForItemAt
com que seja chamado novamente usando o novo tamanho da visualização da coleção. No seu caso, ele deve ser capaz de atualizar dadas as novas restrições disponíveis no layout.fonte
Em seu
viewDidLayoutSubviews
, defina aestimatedItemSize
largura total (layout refere-se ao objeto UICollectionViewFlowLayout):Em sua célula, certifique-se de que suas restrições tocam as partes superior e inferior da célula (o código a seguir usa cartografia para simplificar a configuração das restrições, mas você pode fazer isso com NSLayoutConstraint ou IB se desejar):
Voila, suas células irão crescer automaticamente em altura!
fonte
Nenhuma das soluções funcionou para mim, pois preciso da largura dinâmica para me adaptar à largura dos iPhones.
fonte
Do iOS 10, temos uma nova API no layout de fluxo para fazer isso.
Tudo o que você precisa fazer é definir o seu
flowLayout.estimatedItemSize
para uma nova constanteUICollectionViewFlowLayoutAutomaticSize
,.Fonte
fonte
AutoLayout pode ser usado para dimensionamento automático de células em CollectionView em 2 etapas fáceis:
flowLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
collectionView(:cellForItemAt:)
para limitar a largura de contentView à largura de collectionView.É isso que você obterá o resultado desejado. Consulte a essência a seguir para obter o código completo:
Referência / Créditos:
Captura de tela:
fonte
Você deve herdar a classe UICollectionViewDelegateFlowLayout em seu collectionViewController. Em seguida, adicione a função:
Usando isso, você tem o tamanho da largura da largura da tela.
E agora você tem um collectionViewController com linhas como um tableViewController.
Se você quiser que o tamanho da altura de cada célula seja dinamicamente, talvez você deva criar células personalizadas para cada célula de que precisa.
fonte