2013년 12월 28일 토요일

[iOS] Keyboard가 표시될 때, 사라질 때 이벤트와 그 키보드의 위치는?

 iOS에서 키보드가 표시될 때, 입력부분이 아래에 있다면, 화면이 위로 밀려 올라가야 합니다.이 때, 키보드의 크기를 알아야, 현재 화면을 위로 밀어 올릴 수 있습니다.

 UITableViewController는 자동으로 내부적으로 크기를 줄이고, 입력하는 부분을 위로 올려주게 되어 있습니다.

만약 일반적인 ViewController를 사용해서 화면을 구성한 경우에는 위치를 변경해 주어야 합니다.

1. 키보드가 화면에 나타나거나, 사라지는 Event는 무엇이고, 어떻게 알아낼까요?

키보드가 표시될 때, 전달되는 이벤트는.. 
  • UIKeyboardWillShowNotification : 키보드 표시되기 전, 전달되는 이벤트
  • UIKeyboardDidShowNotification : 키보드 표시되고 난 후, 전달되는 이벤트
  • UIKeyboardWillHideNotification : 키보드 사라지기 전,
  • UIKeyboardDidHideNotification : 키보드 사라진 후, 이벤트
  • UIKeyboardWillChangeFrameNotification : 키보드 모양이 바뀌기 전 (iOS5 이상)
  • UIKeyboardDidChangeFrameNotification : 키보드 모양이 바뀐 후 (iOS5 이상)

필요한 이벤트를 알림센터에 등록해서, 각 이벤트에 해당하는 메시지 함수를 호출 할 수 있습니다.
source code

#pragma mark - Keyboard detect function
// Call this method somewhere in your view controller setup code.
- (void)registerForKeyboardNotifications
{
    NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
    [defaultCenter addObserver:self
                      selector:@selector(keyboardWillbeShown:) //표시되기 전
                          name:UIKeyboardWillShowNotification object:nil];
    [defaultCenter addObserver:self
                      selector:@selector(keyboardWasShown:)    //표시된 후
                          name:UIKeyboardDidShowNotification object:nil];
    [defaultCenter addObserver:self
                      selector:@selector(keyboardWillBeHidden:) //사라지기 전
                          name:UIKeyboardWillHideNotification object:nil];
    [defaultCenter addObserver:self
                      selector:@selector(keyboardWasHidden:)    //사라진 후
                          name:UIKeyboardDidHideNotification object:nil];
    
}

2. 호출된 키보드 이벤트 함수에서, 키보드의 크기를 알아야, 다른 컴포넌트의 크기를 조정할 수 있습니다.

 이벤트로 전달되는 NSNotification클래스의 userInfo에 해당 내용이 추가되어 있습니다.
키보드의 크기는 UIKeyboardFrameBeginUserInfoKey를 통해서 읽어 올 수 있는데, 다른 값들은 차이를 알수가 없었습니다.
  • UIKeyboardFrameBeginUserInfoKey : 키보드가 표시되기 시작할 때의 크기를 가지고 있습니다. NSValue형태로 CGRect 값을 가지고 있습니다.
  • UIKeyboardFrameEndUserInfoKey
  • UIKeyboardAnimationCurveUserInfoKey:
  • UIKeyboardCenterBeginUserInfoKey : CGPoint로 키보드 중심 위치?
  • UIKeyboardCenterEndUserInfoKey :   
  • UIKeyboardBoundsUserInfoKey
아래의 소스코드처럼, Begin과 End이 값을 각 이벤트에 따라서 읽어 봤지만 차이가 없네요.
source code
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWillBeShown: (NSNotification *) aNotification
{
    // Get Keyboard Size
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
    CGSize kbSize2 = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
    double anmationDuration = [[info objectForKey:UIKeyboardAnimationCurveUserInfoKey] doubleValue];
    NSLog(@"keyboard Will beShown: %@, %@, duration:%lf", NSStringFromCGSize(kbSize), NSStringFromCGSize(kbSize2), anmationDuration);
}

3. 결과로 나오는 값은 어떻게 될까요?

iPhone 3.5-inch와 4.0-inch의 height의 길이 차이가 나지만, iPad는 Scale이 같으므로 동일한 결과가 나왔습니다.
iPhone Retina 3.5-inch
세로 
 keyboard Will beShown:   {320, 216}, {320, 216}, duration:7.
 keyboard WasShown:       {320, 216}, {320, 216}
 keyboard Will beHidden:  {320, 216}, {320, 216}
 keyboard WasHidden:      {320, 216}, {320, 216} 

가로
 keyboard Will beShown:   {162, 480}, {162, 480}, duration:7.
 keyboard WasShown:       {162, 480}, {162, 480}
 keyboard Will beHidden:  {162, 480}, {162, 480}
 keyboard WasHidden:      {162, 480}, {162, 480}

iPhone Retina 4.0-inch
세로
 keyboard Will beShown:   {320, 216}, {320, 216}, duration:7.000000
 keyboard WasShown:       {320, 216}, {320, 216}
 keyboard Will beHidden:  {320, 216}, {320, 216}
 keyboard WasHidden:      {320, 216}, {320, 216}
가로
 keyboard Will beShown:   {162, 568}, {162, 568}, duration:7.000000
 keyboard WasShown:       {162, 568}, {162, 568} //너비의 차이..
 keyboard Will beHidden:  {162, 568}, {162, 568}
 keyboard WasHidden:      {162, 568}, {162, 568}

iPad
세로
 keyboard Will beShown:   {768, 264},  {768, 264}, duration:7.000000
 keyboard WasShown:       {768, 264},  {768, 264}
 keyboard Will beHidden:  {768, 264},  {768, 264}
 keyboard WasHidden:      {768, 264},  {768, 264}
가로
 keyboard Will beShown:   {352, 1024}, {352, 1024}, duration:7.000000
 keyboard WasShown:       {352, 1024}, {352, 1024}
 keyboard Will beHidden:  {352, 1024}, {352, 1024}
 keyboard WasHidden:      {352, 1024}, {352, 1024}

iPad Retina
세로
 keyboard Will beShown:   {768, 264},  {768, 264}, duration:7.000000
 keyboard WasShown:       {768, 264},  {768, 264} //iPad와 동일.
 keyboard Will beHidden:  {768, 264},  {768, 264}
 keyboard WasHidden:      {768, 264},  {768, 264}
가로
 keyboard Will beShown:   {352, 1024}, {352, 1024}, duration:7.000000
 keyboard WasShown:       {352, 1024}, {352, 1024}
 keyboard Will beHidden:  {352, 1024}, {352, 1024}
 keyboard WasHidden:      {352, 1024}, {352, 1024}