Estou tendo problemas com meu código. Estou tentando mover o UIScrollView
quando estou editando um UITextField
que deve estar oculto pelo teclado pop.
Estou movendo o quadro principal agora porque não sei como 'rolar para cima' no código. Então, eu fiz um pouco de código, está funcionando bem, mas quando eu edito um UItextfield e mudo para outro UITextField
sem pressionar o botão 'voltar', a visualização principal vai muuuuito para cima.
Fiz um NSLog()
com minhas variáveis size, distance e textFieldRect.origin.y como você pode ver abaixo. Quando coloco dois UITextField
no mesmo lugar (origem y) e faço essa 'troca' específica (sem pressionar Enter), obtenho os mesmos números, enquanto meu código funcionou bem para a primeira UITextField
edição, mas não para a segunda edição.
Veja isso:
- (void)textFieldDidBeginEditing:(UITextField *)textField {
{
int size;
CGRect textFieldRect = [self.view.window convertRect:textField.bounds fromView:textField];
size = textFieldRect.origin.y + textFieldRect.size.height;
if (change == FALSE)
{
size = size - distance;
}
if (size < PORTRAIT_KEYBOARD_HEIGHT)
{
distance = 0;
}
else if (size > PORTRAIT_KEYBOARD_HEIGHT)
{
distance = size - PORTRAIT_KEYBOARD_HEIGHT + 5; // +5 px for more visibility
}
NSLog(@"origin %f", textFieldRect.origin.y);
NSLog(@"size %d", size);
NSLog(@"distance %d", distance);
CGRect viewFrame = self.view.frame;
viewFrame.origin.y -= distance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
change = FALSE;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
change = TRUE;
CGRect viewFrame = self.view.frame;
viewFrame.origin.y += distance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
Alguma ideia ?
fonte
activeField.frame
para quadro relativo, poisactiveField
não precisa ser filho imediato deleself.view
. O código atualizado deve ser semelhante a:CGRect aRect = self.view.frame; aRect.size.height -= kbSize.height; CGRect relativeFieldFrame = [activeField convertRect:activeField.frame toView:self.view]; if (!CGRectContainsPoint(aRect, relativeFieldFrame.origin) ) { CGPoint scrollPoint = CGPointMake(0.0, relativeFieldFrame.origin.y-kbSize.height); [self.mainView.scrollView setContentOffset:scrollPoint animated:YES]; }
UIKeyboardFrameEndUserInfoKey
chave no iOS 11 porqueUIKeyboardFrameBeginUserInfoKey
muitas vezes me dava uma altura de zero.Acabei de implementar isso com o Swift 2.0 para iOS9 no Xcode 7 (beta 6), funciona bem aqui.
Editado para Swift 3
Parece que você só precisa definir o
contentInset
escrollIndicatorInset
com o Swift 3, o scrolling / contentOffset é feito automaticamente.fonte
Todas as respostas aqui parecem esquecer as possibilidades da paisagem. Se você quiser que isso funcione quando o dispositivo for girado para uma visualização de paisagem, você terá problemas.
O truque aqui é que, embora a visualização reconheça a orientação, o teclado não. Isso significa que em paisagem, a largura do teclado é na verdade sua altura e vice-versa.
Para modificar a maneira recomendada pela Apple de alterar as inserções de conteúdo e obter suporte para a orientação paisagem, eu recomendaria usar o seguinte:
A parte a se prestar atenção aqui é a seguinte:
O que faz é detectar em qual orientação o dispositivo está. Se for paisagem, ele irá 'trocar' os valores de largura e altura da variável keyboardSize para garantir que os valores corretos estejam sendo usados em cada orientação.
fonte
Solução Swift 4 :
fonte
UIKeyboardFrameBeginUserInfoKey
paraUIKeyboardFrameEndUserInfoKey
UIKeyboardWillShow
,UIKeyboardWillHide
EUIKeyboardFrameBeginUserInfoKey
foram renomeados paraUIResponder.keyboardWillShowNotification
,UIResponder.keyboardWillHideNotification
, eUIResponder.keyboardFrameBeginUserInfoKey
.Para isso, não há necessidade de muita codificação, é muito fácil como o código abaixo: -
seu texto todo arquivado em UIScrollview da ponta como esta imagem: -
YourViewController.h
conecte IBOutlet do nib e também conecte cada delegado de UItextfiled e scrollview delegado do NIB
NOTA se o delegado arquivado por texto não estiver conectado, então nenhum método está funcionando, certifique-se de que todos os iBOulate e delegado estejam conectados corretamente
fonte
Recomendação da Apple recodificada em Swift + Usando UIScrollView com Auto Layout no iOS (com base nos seguintes links: link 1 , link 2 , link 3 ):
fonte
A única coisa que eu atualizaria no código da Apple é o método keyboardWillBeHidden: para fornecer uma transição suave.
fonte
Aqui está uma resposta compatível com Swift 3 , que também funcionará com controladores de visualização dentro de um controlador de navegação - pois eles irão alterar a
contentInset.top
propriedade de visualização de rolagem .fonte
Solução Swift 4.2 que leva em conta as alturas possíveis de UIToolbar e UITabBar.
E, se você tiver como alvo o <iOS 9, terá que cancelar o registro do observador em algum momento (obrigado Joe )
fonte
Descobri que as respostas acima estão desatualizadas. Também não é perfeito ao rolar.
Aqui está uma versão rápida.
Ele rolará para a direita abaixo do textField, sem espaço livre. E ele vai restaurar a forma como era como na primeira vez.
fonte
É isso que estou usando. É simples e funciona bem.
Use a
UITextField
chamada de delegadotextFieldDidBeginEditing:
para mudar sua visão para cima e também adicione um observador de notificação para retornar a visão ao normal quando o teclado se esconde:fonte
Este é o código final com melhorias em Swift
fonte
Uma das soluções mais fáceis é usar o seguinte protocolo:
Quando você quiser usar este protocolo, você só precisa estar em conformidade com ele e atribuir sua visualização de rolagem em seu controlador da seguinte forma:
fonte
Eu faria isso assim. É muito código, mas garante que o textField atualmente em foco esteja centralizado verticalmente no 'espaço disponível':
Observe que a
- (IBAction)textFieldGotFocus:
ação está ligada a cadaDidBeginEditing
estado de textField .Além disso, seria um pouco melhor obter a duração da animação da notificação do teclado e usá-la para a animação scrollview em vez de um valor fixo, mas me processe, isso foi bom o suficiente para mim;)
fonte
Use a seguinte extensão se não quiser calcular muito:
E talvez você queira manter seu UITextField sempre visível:
fonte
Experimente este código no Swift 3:
fonte
Solução Swift 5 baseada na solução Masa acima - mudanças em relação a ela:
keyboardFrameEndUserInfoKey
vez dekeyboardFrameBeginUserInfoKey
, porquekeyboardFrameBeginUserInfoKey
pode na primeira exibição retornar outro valor, conforme descrito por exemplo aqui: a altura do teclado varia quando apareceUIResponder.keyboardWillShowNotification
/ emUIResponder.keyboardWillHideNotification
vez deNSNotification.Name.UIKeyboardDidShow
/NSNotification.Name.UIKeyboardDidHide
Código:
fonte
Na verdade, você não precisa de um UIScrollView para fazer isso. Usei este código e funciona para mim:
fonte
Você pode rolar usando a propriedade
contentOffset
emUIScrollView
, por exemplo,Também existe um método para fazer a rolagem animada.
Quanto à razão pela qual sua segunda edição não está rolando corretamente, pode ser porque você parece assumir que um novo teclado aparecerá toda vez que a edição começar. Você pode tentar verificar se já ajustou para a posição visível do "teclado" (e da mesma forma verificar a visibilidade do teclado no momento, antes de reverter).
Uma solução melhor pode ser ouvir a notificação do teclado, por exemplo:
fonte
Eu sei que é uma velha questão agora, mas pensei que poderia ajudar outras pessoas. Eu queria algo um pouco mais fácil de implementar para alguns aplicativos que tinha, então criei uma aula para isso. Você pode baixá-lo aqui se desejar: https://github.com/sdernley/iOSTextFieldHandler
É tão simples quanto configurar todos os UITextFields para ter um delegado próprio
E, em seguida, adicionar isso ao seu controlador de visualização com o nome do seu scrollView e botão de envio
fonte
A seguir estão minhas soluções que funcionam (5 etapas)
Passo 1: Adicionar um observador para capturar qual UITEXTFIELD ou UITEXTVIEW ShoudBeginEditing (onde o objeto é iniciado ou ViewDidLoad.
Passo 2: Publique uma notificação quando ..ShouldBeginEditing with OBJECT de UITEXTFIELD ou UITEXTVIEW
Etapa 3: o método que (a Etapa 1 chama) atribui o UITEXTFIELD ou UITEXTVIEW atual
Etapa 4: Adicionar o observador de teclado UIKeyboardWillShowNotification (mesmo lugar da Etapa 1)
e método:
Etapa 5: Adicionar o observador de teclado UIKeyboardWillHideNotification (mesmo lugar da etapa 1)
e método:
Lembre-se de remover observadores!
fonte
Usei esta resposta fornecida por Sudheer Palchuri https://stackoverflow.com/users/2873919/sudheer-palchuri https://stackoverflow.com/a/32583809/6193496
Em ViewDidLoad, registre as notificações:
Adicione os métodos de observador abaixo que fazem a rolagem automática quando o teclado aparece.
fonte
Minha solução tem 4 etapas:
- Etapa 1: a função escuta quando o teclado aparece
- Etapa 2: a função escuta quando o teclado desaparece
- Etapa 3: adicione essas funções à central de notificações:
- Etapa 4: remover a escuta quando visualizar o controlador desaparecer
fonte