Search code examples
iphoneobjective-ciosuiviewcore-animation

iOS 5's Messages.app Keyboard Accessory View Behaviour


Messages.app Screenshot

Can anyone explain how best to emulate the behaviour the "accessory view" (in inverted comma's as I don't actually believe it to be an accessory view) in iOS 5's Messages.app displays, in that I want a view that gives the impression it's fixed to the top of the keyboard, but which remains on screen when the keyboard is dismissed.


Solution

  • It's probably a separate view that gets re-positioned using an animation that has the same duration as the keyboard animation.

    Try observing the UIKeyboardWillShowNotification and UIKeyboardWillHideNotification and in your handlers get the keyboard's animation duration and frame and start your own animation to re-position the view so that it will appear to move along with the keyboard. Some similar code I use is below:

    - (void)registerKeyboardNotifications {
        // Register for keyboard notifications
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(keyboardWillShow:)
                                                     name:UIKeyboardWillShowNotification
                                                   object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(keyboardWillHide:)
                                                     name:UIKeyboardWillHideNotification
                                                   object:nil];
    }
    
    - (void)unregisterKeyboardNotifications {
        [[NSNotificationCenter defaultCenter] removeObserver:self 
                                                        name:UIKeyboardWillShowNotification 
                                                      object:nil];    
        [[NSNotificationCenter defaultCenter] removeObserver:self 
                                                        name:UIKeyboardWillHideNotification 
                                                      object:nil];    
    }
    
    - (void)keyboardWillShow:(NSNotification*)aNotification {
        NSDictionary* info = [aNotification userInfo];
        CGRect kbFrameBeginFrame = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
        CGRect kbFrameEndFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];    
        NSTimeInterval animDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];    
        UIViewAnimationCurve animCurve = [[info objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];    
    
        NSLog(@"\nFrame Begin = %@\nFrame End = %@\nAnimation Duration = %f\nAnimation Curve = %i", 
                 NSStringFromCGRect(kbFrameBeginFrame), NSStringFromCGRect(kbFrameEndFrame), animDuration, animCurve);
    
        _showKeyboard = YES;
        [self adjustUIForKeyboard:kbFrameEndFrame.size animDuration:animDuration];
    }
    
    - (void)keyboardWillHide:(NSNotification*)aNotification {
        NSDictionary* info = [aNotification userInfo];
        CGRect kbFrameBeginFrame = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
        CGRect kbFrameEndFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];    
        NSTimeInterval animDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];    
        UIViewAnimationCurve animCurve = [[info objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];   
    
        NSLog(@"\nFrame Begin = %@\nFrame End = %@\nAnimation Duration = %f\nAnimation Curve = %i", 
                 NSStringFromCGRect(kbFrameBeginFrame), NSStringFromCGRect(kbFrameEndFrame), animDuration, animCurve);
    
        _showKeyboard = NO;
        [self adjustUIForKeyboard:kbFrameEndFrame.size animDuration:animDuration];
    }
    
    /**
     * Adjust the UI elements so that views are visible when keyboard is visible or hidden
     */
    - (void)adjustUIForKeyboard:(CGSize)keyboardSize animDuration:(NSTimeInterval)duration {    
        [UIView animateWithDuration:duration
                         animations:^(void) {
                             // When keyboard is showing we adjust up and vice versa for a hidden keyboard
                             if (_showKeyboard) {
                                 // Set your view's frame values 
                             } else {
                                 // Set your view's frame values                              
                             } 
                         }
                         completion:NULL];
    }