2010-08-23 15 views
60

¿Hay alguna forma de obtener el tamaño del UIKeyboard programáticamente? 216.0f altura y 162.0f altura en el paisaje.Cómo obtener el tamaño de UIKeyboard con Apple iPhone SDK

Los que siguen parecen estar privados. ¿Hay alguna manera de que funciona sin ningún tipo de aviso, tanto en el iPhone OS 3.0 SDK y 4.0 iPhone OS SDK para hacer esto ..

CGSize keyBoardSize = [[[note userInfo] 
objectForKey:UIKeyboardBoundsUserInfoKey]CGRectValue].size; 

Gracias, Tharindu

+2

En 2011, Apple finalmente tiene una buena introducción acerca de la manipulación y el tamaño del teclado: http://developer.apple.com/library/ios/#documentation/StringsTextFonts/Conceptual/TextA ndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html. –

Respuesta

130

Usted puede obtener el tamaño del teclado del diccionario userInfo utilizando el UIKeyboardFrameBeginUserInfoKey y el UIKeyboardFrameEndUserInfoKey en su lugar.

Estas dos claves devuelven una instancia NSValue que contiene un que mantiene la posición y el tamaño del teclado en los puntos inicial y final de la animación show/hide del teclado.

Editar:

Para aclarar, el diccionario userInfo proviene de una NSNotification ejemplo. Se pasa a su método que se registre con un observador. Por ejemplo,

- (void)someMethodWhereYouSetUpYourObserver 
{ 
    // This could be in an init method. 
    [[NSNotificationCenter defaultCenter] addObserver:self 
        selector:@selector(myNotificationMethod:) 
        name:UIKeyboardDidShowNotification 
        object:nil]; 
} 

- (void)myNotificationMethod:(NSNotification*)notification 
{ 
    NSDictionary* keyboardInfo = [notification userInfo]; 
    NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey]; 
    CGRect keyboardFrameBeginRect = [keyboardFrameBegin CGRectValue]; 
} 

Edición 2:

También, por favor no se olvide de eliminar a sí mismo como un observador en su método dealloc! Esto es para evitar un bloqueo que ocurriría cuando el centro de notificaciones intente notificar a su objeto después de haber sido liberado.

+1

Lamento revivir a un zombi aquí, pero ¿de dónde viene el diccionario userInfo? ¿A qué objeto llamo '-userInfo' para obtenerlo? –

+2

¡Ningún problema! Acabo de editar mi respuesta, ¿eso ayuda? –

+1

Sí, gracias, eso es lo que me faltaba –

44

En su lugar, debe usar el UIKeyboardWillChangeFrameNotification, porque algunos teclados internacionales, como el teclado chino, cambiarán los marcos durante el uso. También asegúrese de convertir el CGRect en la vista correcta, para uso en el paisaje.

//some method like viewDidLoad, where you set up your observer. 
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChange:) name:UIKeyboardWillChangeFrameNotification object:nil]; 

- (void)keyboardWillChange:(NSNotification *)notification { 
    CGRect keyboardRect = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; 
    keyboardRect = [self.view convertRect:keyboardRect fromView:nil]; //this is it! 
} 
+3

+1 para una gran respuesta. Muy útil también funciona con teclados de terceros en iOS 8 – Bocaxica

+0

Obtengo un CGRect diferente de '[self.view convertRect: keyboardRect fromView: nil]' en iOS 8 que en iOS 7 ... –

+0

+1 for ' UIKeyboardFrameEndUserInfoKey'! De alguna manera había conseguido usar 'UIKeyboardFrameBeginUserInfoKey', que en realidad es del tamaño del teclado * antes de * el cambio de tamaño y me preguntaba por qué todo estaba en mal estado. – devios1

3

Así es como finalmente funcioné. Combiné sugerencias y códigos de diferentes respuestas. Características: despedir teclado, moviéndose por encima de los campos de texto del teclado durante la edición y el establecimiento de "Siguiente" y el teclado de retorno type.REPLACE "Hecho" "..." con más campos

static const CGFloat ANIMATION_DURATION = 0.4; 
static const CGFloat LITTLE_SPACE = 5; 
CGFloat animatedDistance; 
CGSize keyboardSize; 

@interface ViewController() <UITextFieldDelegate> 
@property (weak, nonatomic) IBOutlet UITextField *firstNameTXT; 
    .....// some other text fields 
@property (weak, nonatomic) IBOutlet UITextField *emailTXT; 
@end 

@implementation ViewController 
- (void)viewDidLoad{ 
..... 
// add tap gesture to help in dismissing keyboard 
UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc] 
             initWithTarget:self 
             action:@selector(tapScreen:)];// outside textfields 

[self.view addGestureRecognizer:tapGesture]; 

// set text fields return key type to Next, last text field to Done 
[self.firstNameTXT setReturnKeyType:UIReturnKeyNext]; 
..... 
[self.emailTXT setReturnKeyType:UIReturnKeyDone]; 

// set text fields tags 
[self.firstNameTXT setTag:0]; 
....// more text fields 
[self.emailTXT setTag:5]; 

// add keyboard notification 
[[NSNotificationCenter defaultCenter] addObserver:self  selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil]; 
} 
[[NSNotificationCenter defaultCenter] addObserver:self  selector:@selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil]; 
} 

// dismiss keyboard when tap outside text fields 
- (IBAction)tapScreen:(UITapGestureRecognizer *)sender { 
    if([self.firstNameTXT isFirstResponder])[self.firstNameTXT resignFirstResponder]; 
    ... 
    if([self.emailTXT isFirstResponder])[self.emailTXT resignFirstResponder]; 

    } 
- (BOOL)textFieldShouldReturn:(UITextField *)textField{ 
    if(textField.returnKeyType==UIReturnKeyNext) { 
    // find the text field with next tag 
    UIView *next = [[textField superview] viewWithTag:textField.tag+1]; 
    [next becomeFirstResponder]; 
    } else if (textField.returnKeyType==UIReturnKeyDone || textField.returnKeyType==UIReturnKeyDefault) { 
    [textField resignFirstResponder]; 
} 
return YES; 
} 

// Moving current text field above keyboard 
-(BOOL) textFieldShouldBeginEditing:(UITextField*)textField{ 
    CGRect viewFrame = self.view.frame; 
    CGRect textFieldRect = [self.view.window convertRect:textField.bounds fromView:textField]; 
    CGRect viewRect = [self.view.window convertRect:self.view.bounds fromView:self.view]; 
    CGFloat textFieldBottomLine = textFieldRect.origin.y + textFieldRect.size.height + LITTLE_SPACE;// 

    CGFloat keyboardHeight = keyboardSize.height; 

    BOOL isTextFieldHidden = textFieldBottomLine > (viewRect.size.height - keyboardHeight)? TRUE :FALSE; 
    if (isTextFieldHidden) { 
    animatedDistance = textFieldBottomLine - (viewRect.size.height - keyboardHeight) ; 
    viewFrame.origin.y -= animatedDistance; 
    [UIView beginAnimations:nil context:NULL]; 
    [UIView setAnimationBeginsFromCurrentState:YES]; 
    [UIView setAnimationDuration:ANIMATION_DURATION]; 
    [self.view setFrame:viewFrame]; 
    [UIView commitAnimations]; 
    } 
    return YES; 
} 

-(void) restoreViewFrameOrigionYToZero{ 
    CGRect viewFrame = self.view.frame; 
    if (viewFrame.origin.y != 0) { 
    viewFrame.origin.y = 0; 
    [UIView beginAnimations:nil context:NULL]; 
    [UIView setAnimationBeginsFromCurrentState:YES]; 
    [UIView setAnimationDuration:ANIMATION_DURATION]; 
    [self.view setFrame:viewFrame]; 
    [UIView commitAnimations]; 
    } 
} 

-(void)keyboardDidShow:(NSNotification*)aNotification{ 
    NSDictionary* info = [aNotification userInfo]; 
    keyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; 
} 

-(void)keyboardDidHide:(NSNotification*)aNotification{ 
    [self restoreViewFrameOrigionYToZero];// keyboard is dismissed, restore frame view to its zero origin 
} 
@end 
0

sobre SWIFT 4

override func viewDidLoad() { 
    super.viewDidLoad() 
    NotificationCenter.default.addObserver(self, selector: #selector(getInfo(notif:)), name: .UIKeyboardDidShow , object: nil) 
} 

y luego:

@objc func getInfo(notif: NSNotification) -> Void { 
    guard let userInfo = notif.userInfo else {return} 

    if let myData = userInfo["UIKeyboardFrameBeginUserInfoKey"] as? CGRect { 
     print(myData.width) 
     print(myData.height) 
    } 
} 
Cuestiones relacionadas