Depois de muita tentativa e erro, estou desistindo e fazendo a pergunta. Eu já vi muitas pessoas com problemas semelhantes, mas não consigo obter todas as respostas para funcionar corretamente.
Eu tenho um UITableView
que é composto de células personalizadas. As células são compostas por 5 campos de texto próximos um do outro (como uma grade).
Quando tento rolar e editar as células na parte inferior do UITableView
, não consigo posicionar minhas células corretamente acima do teclado.
Eu já vi muitas respostas falando sobre a alteração do tamanho das visualizações, etc ... mas nenhuma delas funcionou muito bem até agora.
Alguém poderia esclarecer a maneira "certa" de fazer isso com um exemplo de código concreto?
Respostas:
Se você usar UITableViewController em vez de UIViewController, ele fará isso automaticamente.
fonte
A função que faz a rolagem pode ser muito mais simples:
É isso aí. Sem cálculos.
fonte
contentInset
, que aparentemente não é levado em consideração ao solicitarvisibleRows
ouindexPathsForVisibleRows
.Estou fazendo algo muito semelhante, é genérico, não há necessidade de calcular algo específico para o seu código. Basta verificar as observações no código:
Em MyUIViewController.h
No MyUIViewController.m
Versão Swift 1.2+:
fonte
[tableView scrollToRowAtIndexPath: indexPath atScrollPosition: UITableViewScrollPositionMiddle animated: YES];
MyAppDelegate *appDelegate = (MyAppDelegate*)[[UIApplication sharedApplication] delegate]; CGFloat tabBarHeight = appDelegate.tabBarController.tabBar.frame.size.height;
Subtraia tabBarHeight da altura do teclado onde quer que você use a altura do teclado.A solução mais simples para o Swift 3 , baseada na solução Bartłomiej Semańczyk :
fonte
Notification
vez deNSNotification
seria mais "Swift 3-y" :-)Eu tive o mesmo problema, mas notei que ele aparece apenas em uma exibição. Então comecei a procurar as diferenças nos controladores.
Eu descobri que o comportamento de rolagem é definido na
- (void)viewWillAppear:(BOOL)animated
super instância.Portanto, certifique-se de implementar assim:
E não importa se você usa
UIViewController
ouUITableViewController
; verifiquei colocando aUITableView
como uma subview de self.view noUIViewController
. Foi o mesmo comportamento. A visualização não permitia rolar se a chamada[super viewWillAppear:animated];
estava ausente.fonte
Eu posso ter perdido isso, pois não li o post inteiro aqui, mas o que eu criei parece enganosamente simples. Eu não passei por isso, testando em todas as situações, mas parece que deve funcionar muito bem.
simplesmente ajuste o contentInset da tableview pela altura do teclado e role a célula para baixo:
e claro
isso é muito simples? estou esquecendo de algo? até agora está funcionando bem para mim, mas como eu disse, não o coloquei no espremedor ...
fonte
[aNotification.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue]
contentInset
nem alterará muito os limites da rolagem.Acho que encontrei a solução para combinar com o comportamento dos aplicativos da Apple.
Primeiro, em seu viewWillAppear: assine as notificações do teclado para saber quando o teclado será exibido e oculto e o sistema informará o tamanho do teclado, mas não se esqueça de cancelar o registro em seu viewWillDisappear :.
Implemente os métodos semelhantes aos abaixo para ajustar o tamanho do seu tableView para corresponder à área visível assim que o teclado aparecer. Aqui, acompanho o estado do teclado separadamente para que eu possa escolher quando definir o tableView de volta à sua altura máxima, pois você recebe essas notificações a cada alteração de campo. Não se esqueça de implementar keyboardWillHide: e escolha um local apropriado para corrigir o tamanho do seu tableView.
Agora, aqui está o bit de rolagem: primeiro calculamos alguns tamanhos, depois vemos onde estamos na área visível e definimos o retângulo que queremos rolar para ser a meia vista acima ou abaixo do meio do campo de texto onde está a vista. Nesse caso, temos uma matriz de UITextFields e uma enumeração que os acompanha, portanto, multiplicar o rowHeight pelo número da linha nos fornece o deslocamento real do quadro nessa exibição externa.
Isso parece funcionar muito bem.
fonte
UIKeyboardBoundsUserInfoKey
foi descontinuado a partir do iOS 3.2. Veja minha solução abaixo que funciona em todas as versões atuais do iOS ≥ 3.0. / @ iPhoneDevSe você pode usar
UITableViewController
, você obtém a funcionalidade gratuitamente. Às vezes, no entanto, isso não é uma opção, especificamente se você precisar de várias visualizações, não apenas oUITableView
.Algumas das soluções apresentadas aqui não funcionam no iOS ≥4, outras não no iPad ou no modo paisagem, algumas não funcionam nos teclados Bluetooth (onde não queremos rolagem), outras não. funciona ao alternar entre vários campos de texto. Portanto, se você escolher qualquer solução, teste esses casos. Esta é a solução que
usamosusada no InAppSettingsKit :Aqui está o código completo da classe no InAppSettingsKit. Para testá-lo, use o painel filho "Lista Completa", onde você pode testar os cenários mencionados acima.
fonte
A solução mais simples para Swift :
fonte
Espero que vocês já tenham uma solução lendo tudo isso. Mas encontrei minha solução da seguinte maneira. Estou esperando que você já tenha um celular
UITextField
. Portanto, na preparação, mantenha o índice da linha na tag do campo de texto.Crie uma
activeTextField
instânciaUITextField
com escopo global, como abaixo:Então, agora você acabou de copiar e colar meu código no final. E também não se esqueça de adicionar
UITextFieldDelegate
Registra o teclado
notifications
Teclado de alças
Notifications
:Chamado quando o
UIKeyboardDidShowNotification
é enviado.Chamado quando o
UIKeyboardWillHideNotification
é enviadoAgora, resta uma coisa: chame o
registerForKeyboardNotifications
método para oViewDidLoad
método da seguinte maneira:Você está pronto, espero que sua
textFields
vontade não fique mais oculta pelo teclado.fonte
Combinando e preenchendo os espaços em branco de várias respostas (em particular Ortwin Gentz, usuário 98013) e outra postagem, isso funcionará imediatamente para o SDK 4.3 em um iPad no modo Retrato ou Paisagem:
fonte
Se você usar uma visualização uitabl para colocar seus campos de texto ( de Jeff Lamarche ), basta rolar a visualização de tabela usando o método delegate dessa maneira.
(Nota: meus campos de texto são armazenados em uma matriz com o mesmo índice que a linha da tableview)
fonte
As notificações do teclado funcionam, mas o código de exemplo da Apple para isso pressupõe que a visualização de rolagem é a visualização raiz da janela. Geralmente não é esse o caso. Você precisa compensar as barras de guias, etc., para obter o deslocamento correto.
É mais fácil do que parece. Aqui está o código que eu uso em um UITableViewController. Possui duas variáveis de instância, hiddenRect e keyboardShown.
fonte
UIKeyboardCenterEndUserInfoKey
eUIKeyboardBoundsUserInfoKey
estão obsoletos no iOS 3.2. Veja minha solução abaixo que funciona em todas as versões atuais do iOS ≥ 3.0.Se você usar
Three20
, use aautoresizesForKeyboard
propriedade Basta definir no-initWithNibName:bundle
método do seu controlador de exibiçãoIsso cuida de:
Feito e feito.
fonte
Minha abordagem:
Subclasse primeiro UITextField e adiciono uma propriedade indexPath. No método cellFor ..., entrego a propriedade indexPath.
Então eu adiciono o seguinte código:
para o textFieldShould / WillBegin ... etc.
Quando o teclado desaparece, você deve invertê-lo com:
fonte
Uma solução mais alinhada ao fluxo. Ele entra nos métodos de delegação UITextField, para que não exija alterações com notificações do UIKeyboard.
Notas de implementação:
kSettingsRowHeight - a altura de um UITableViewCell.
offsetTarget e offsetThreshold são baseados em kSettingsRowHeight. Se você usar uma altura de linha diferente, defina esses valores para a propriedade y do ponto. [alt: calcula o deslocamento da linha de uma maneira diferente.]
}
}
fonte
Use o
UITextField's
delegate
método:Rápido
Objetivo-C
fonte
Solução completa Swift 4.2
Eu criei o GIST com um conjunto de protocolos que simplifica o trabalho com a adição de espaço extra quando o teclado é mostrado, oculto ou alterado.
Características :
Uso
Exemplo de uso básico no controlador de exibição que contém alguma exibição de rolagem (a exibição de tabela também é suportada, é claro).
Núcleo: quadro muda observador
O protocolo
KeyboardChangeFrameObserver
dispara um evento toda vez que o quadro do teclado é alterado (incluindo exibição, ocultação, alteração do quadro).addKeyboardFrameChangesObserver()
paraviewWillAppear()
ou método semelhante.removeKeyboardFrameChangesObserver()
paraviewWillDisappear()
ou método semelhante.Implementação: visualização de rolagem
ModifableInsetsOnKeyboardFrameChanges
O protocolo adicionaUIScrollView
suporte ao protocolo principal. Ele altera as inserções da exibição de rolagem quando o quadro do teclado é alterado.Sua turma precisa definir a visualização de rolagem; as inserções de uma pessoa serão aumentadas / diminuídas nas alterações no quadro do teclado.
fonte
Como você possui campos de texto em uma tabela, a melhor maneira é redimensionar a tabela - você precisa definir o tableView.frame para ter uma altura menor pelo tamanho do teclado (acho que cerca de 165 pixels) e expandi-lo novamente quando o teclado é descartado.
Opcionalmente, também é possível desativar a interação do usuário para o tableView nesse momento, se você não desejar que o usuário role.
fonte
Isso funciona perfeitamente e também no iPad.
fonte
Tentei quase a mesma abordagem e criei um código mais simples e menor para a mesma. Eu criei um IBOutlet iTextView e associado ao UITextView no IB.
fonte
Então, depois de horas de trabalho exaustivo tentando usar essas soluções atuais (e totalmente falhas), finalmente consegui que as coisas funcionassem bem e as atualizei para usar os novos blocos de animação. Minha resposta é inteiramente baseada em resposta de Ortwin acima .
Portanto, por qualquer motivo, o código acima simplesmente não estava funcionando para mim. Minha configuração parecia bastante semelhante às outras, mas talvez porque eu estivesse em um iPad ou 4.3 ... não faço ideia. Estava fazendo algumas contas malucas e tirando minha foto da tela.
Veja o resultado final da minha solução: http://screencast.com/t/hjBCuRrPC (ignore a foto. :-P)
Então, eu fui com a essência do que Ortwin estava fazendo, mas mudei como estava fazendo algumas contas para adicionar a origem.y e tamanho. altura da minha exibição de tabela com a altura do teclado. Quando subtraio a altura da janela desse resultado, ele me diz quantas interseções eu tenho. Se for maior que 0 (também conhecido como sobreposição), realizo a animação da altura do quadro.
Além disso, houve alguns problemas de redesenho que foram resolvidos por 1) Aguardando a rolagem para a célula até a animação ser concluída e 2) usando a opção UIViewAnimationOptionBeginFromCurrentState ao ocultar o teclado.
Algumas coisas a serem observadas.
Novamente, eu não teria chegado perto dessa resposta se Ortwin não fornecesse o ponto crucial dela. Aqui está o código:
fonte
Este solução funciona para mim, observe a linha
Você pode alterar o valor 160 para combinar com o trabalho com você
fonte
Tópico de discussão muito interessante, eu também enfrentei o mesmo problema pode ser pior porque
Então, leia os tópicos aqui e implementei minha versão, o que me ajudou a aumentar meu conteúdo no iPad no modo paisagem . Aqui está o código (isso não é à prova de idiotas e tudo, mas corrigiu meu problema) Primeiro você precisa ter um delegado em sua classe de célula personalizada, que na edição começa, envia o campo de texto para o seu viewcontroller e define o activefield = theTextField
// IMPLEMENTADO PARA MANUSEAR SOMENTE O MODO PAISAGEM
// Chamado quando o UIKeyboardWillHideNotification é enviado
-anoop4real
fonte
Acabei de resolver esse problema sozinho depois de me referir a uma série de soluções encontradas via Google e Stack Overflow.
Primeiro, verifique se você configurou um IBOutlet do seu UIScrollView. Depois, verifique atentamente o Apple Doc: Keyboard Management . Por fim, se você pode rolar o plano de fundo, mas o teclado ainda cobre os campos de texto, consulte este trecho de código:
A principal diferença entre esta peça e a da Apple está na condição if. Acredito que o cálculo da Apple da distância de rolagem e da condição de se o campo de texto coberto pelo teclado não é preciso, então fiz minha modificação como acima.
Deixe-me saber se funciona
fonte
Um exemplo no Swift, usando o ponto exato do campo de texto em Get indexPath of UITextField no UITableViewCell with Swift :
fonte
Outro método fácil (funciona apenas com uma seção)
fonte
Se o seu UITableView for gerenciado por uma subclasse de UITableViewController e não UITableView, e o representante do campo de texto for o UITableViewController, ele deverá gerenciar toda a rolagem automaticamente - todos esses outros comentários são muito difíceis de implementar na prática.
Para um bom exemplo, consulte o projeto de código de exemplo da apple: TaggedLocations.
Você pode ver que ele rola automaticamente, mas não parece haver nenhum código que faça isso. Este projeto também possui células de exibição de tabela personalizadas; portanto, se você criar seu aplicativo com ele como guia, deverá obter o resultado desejado.
fonte
Aqui está como eu fiz esse trabalho, que é uma mistura das respostas de Sam Ho e Marcel W, e algumas das minhas próprias correções de erros foram feitas no meu código de baixa qualidade. Eu estava usando um UITableViewController. A tabela agora é redimensionada corretamente quando o teclado é mostrado.
1)
viewDidLoad
Adicionei:self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
2) Eu tinha esquecido de chamar os
super
equivalentes emviewWillAppear
eawakeFromNib
. Eu os adicionei de volta.fonte
UITableViewController
faz a rolagem automaticamente, de fato. A diferença em relação ao uso de aUIViewController
é que você precisa criar itens do Navbar-Button programaticamente usando oNavigationController
, ao usar aTableViewController
.fonte