Eu tenho uma visão que é apresentada completamente usando o layout automático programaticamente. Eu tenho um UITextView no meio da exibição com itens acima e abaixo dele. Tudo funciona bem, mas quero poder expandir o UITextView à medida que o texto é adicionado. Isso deve empurrar tudo abaixo para baixo à medida que se expande.
Eu sei como fazer isso da maneira "molas e suportes", mas existe uma maneira de layout automático de fazer isso? A única maneira de pensar é removendo e adicionando novamente a restrição toda vez que ela precisar crescer.
ios
uitextview
autolayout
nslayoutconstraint
tharris
fonte
fonte
Respostas:
A visualização que contém UITextView terá seu tamanho atribuído
setBounds
pelo AutoLayout. Então, foi o que eu fiz. A superview é inicialmente configurada como todas as outras restrições e, no final, coloquei uma restrição especial para a altura do UITextView e salvei-a em uma variável de instância.No
setBounds
método, alterei o valor da constante.fonte
textViewDidChange
isso deve poupar algum aborrecimento subclasse e escrevendo código ...textViewDidChange:
não será chamado ao adicionar texto ao UITextView programaticamente.Resumo: desative a rolagem da exibição de texto e não restrinja sua altura.
Para fazer isso programaticamente, insira o seguinte código em
viewDidLoad
:Para fazer isso no Interface Builder, selecione a exibição de texto, desmarque Rolagem ativada no Inspetor de atributos e adicione as restrições manualmente.
Nota: Se você tiver outras visualizações acima / abaixo da visualização de texto, considere usar a
UIStackView
para organizar todas elas.fonte
intrinsicContentSize
dessa forma- (CGSize)intrinsicContentSize { CGSize size = [super intrinsicContentSize]; if (self.text.length == 0) { size.height = UIViewNoIntrinsicMetric; } return size; }
. Diga-me se está funcionando para você. Não testei sozinho.Aqui está uma solução para pessoas que preferem fazer tudo por layout automático:
Inspetor de tamanho:
Defina a prioridade da resistência à compactação de conteúdo na vertical para 1000.
Diminua a prioridade da altura da restrição clicando em "Editar" em Restrições. Apenas faça menos que 1000.
No Inspetor de atributos:
fonte
O UITextView não fornece um intrinsicContentSize, portanto você precisa subclassificá-lo e fornecer um. Para fazê-lo crescer automaticamente, invalide o intrinsicContentSize em layoutSubviews. Se você usar algo diferente do contentInset padrão (que eu não recomendo), pode ser necessário ajustar o cálculo intrinsicContentSize.
fonte
setScrollEnabled:
para sempre configurá-lo,NO
você obterá um loop infinito para um tamanho de conteúdo intrínseco cada vez maior.[textView sizeToFit]
otextViewDidChange:
retorno de chamada delegado para o Auto Layout aumentar ou diminuir a exibição de texto (e recalcular qualquer restrição dependente) após cada pressionamento de tecla.-(void)layoutSubviews
e envolva todo o código-(CGSize)intrinsicContentSize
comversion >= 7.0f && version < 7.1f
+else return [super intrinsicContentSize];
Você pode fazer isso através do storyboard, basta desativar "Rolagem ativada" :)
fonte
Descobri que não é totalmente incomum em situações em que você ainda pode precisar de isScrollEnabled definido como true para permitir uma interação razoável da interface do usuário. Um exemplo simples disso é quando você deseja permitir uma exibição de texto com expansão automática, mas ainda limita sua altura máxima a algo razoável em um UITableView.
Aqui está uma subclasse do UITextView que eu criei que permite expansão automática com layout automático, mas que você ainda pode restringir a uma altura máxima e que gerenciará se a exibição é rolável dependendo da altura. Por padrão, a exibição será expandida indefinidamente se você tiver suas restrições configuradas dessa maneira.
Como bônus, há suporte para incluir texto de espaço reservado semelhante ao UILabel.
fonte
Você também pode fazer isso sem subclassificar
UITextView
. Dê uma olhada na minha resposta para Como dimensionar um UITextView para seu conteúdo no iOS 7?Use o valor desta expressão:
para atualizar o
constant
datextView
altura 'sUILayoutConstraint
.fonte
Uma coisa importante a ser observada:
Como UITextView é uma subclasse de UIScrollView, ela está sujeita à propriedade automaticamenteAdjustsScrollViewInsets de UIViewController.
Se você estiver configurando o layout e o TextView for a primeira subvisão na hierarquia UIViewControllers, ele terá seus contentInsets modificados se a opção AutomaticAdjustsScrollViewInsets for verdadeira, algumas vezes causando comportamento inesperado no layout automático.
Portanto, se você estiver tendo problemas com o layout automático e as visualizações de texto, tente definir
automaticallyAdjustsScrollViewInsets = false
o controlador de exibição ou mover o textView para frente na hierarquia.fonte
Este comentário mais importante
A chave para entender por que a resposta da vitaminwater funciona são três coisas:
contentOffset
é provavelmente nada, mas:Para obter mais informações, consulte objc scrollview e compreendendo scrollview
Ao combinar os três, você entenderia facilmente que precisa permitir que o contentSize intrínseco do textView funcione de acordo com as restrições de AutoLayout do textView para conduzir a lógica. É quase como se seu textView estivesse funcionando como um UILabel
Para que isso aconteça, você precisa desativar a rolagem, que basicamente significa o tamanho do scrollView, o tamanho do contentSize e, no caso de adicionar um containerView, o tamanho do containerView será o mesmo. Quando são iguais, você NÃO tem rolagem. E você teria . Ter significa que você não rolou para baixo. Nem um ponto a menos! Como resultado, o textView será todo estendido.
0
contentOffset
0
contentOffSet
Também não vale nada, o que significa que os limites e o quadro do scrollView são idênticos. Se você rolar 5 pontos para baixo, seu contentOffset seria , enquanto seu seria igual a
0
contentOffset
5
scrollView.bounds.origin.y - scrollView.frame.origin.y
5
fonte
Solução Plug and Play - Xcode 9
Execução automática como
UILabel
, com a detecção de links , seleção de texto , edição e rolagem deUITextView
.Lida automaticamente
Muitas dessas respostas me deixaram 90% lá, mas nenhuma foi à prova de idiotas.
Entre nesta
UITextView
subclasse e você é bom.fonte
A resposta da vitaminwater está funcionando para mim.
Se o texto da sua visualização de texto estiver saltando para cima e para baixo durante a edição, após a configuração
[textView setScrollEnabled:NO];
, definaSize Inspector > Scroll View > Content Insets > Never
.Espero que ajude.
fonte
Coloque o UILabel oculto embaixo da sua visualização de texto. Linhas de rótulo = 0. Defina as restrições do UITextView como iguais ao UILabel (centerX, centerY, largura, altura). Funciona mesmo se você deixar o comportamento de rolagem do textView.
fonte
BTW, criei um UITextView em expansão usando uma subclasse e substituindo o tamanho do conteúdo intrínseco. Descobri um bug no UITextView que você pode querer investigar em sua própria implementação. Aqui está o problema:
A exibição de texto em expansão aumentaria para acomodar o texto em crescimento se você digitar letras únicas por vez. Mas se você colar um monte de texto nele, ele não diminuirá, mas o texto rolará para cima e o texto na parte superior ficará fora de vista.
A solução: Substituir setBounds: na sua subclasse. Por alguma razão desconhecida, a colagem fez com que o valor bounds.origin.y não fosse zee (33 em todos os casos que vi). Então, eu substitui setBounds: para sempre definir o bounds.origin.y como zero. Corrigido o problema.
fonte
Aqui está uma solução rápida:
Esse problema pode ocorrer se você tiver definido a propriedade clipsToBounds como false na sua visualização de texto. Se você simplesmente excluí-lo, o problema desaparece.
fonte
fonte