Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>This solution is based on ComSubVie's one.</p> <p>Advantages:</p> <ul> <li>It supports device rotation - works for all orientations;</li> <li>It doesn't hardcode the values for animation duration and curve, it reads them from the keyboard notification;</li> <li>It utilizes <code>UIKeyboardWillShowNotification</code> instead of <code>UIKeyboardDidShowNotification</code> to sync keyboard animation and custom actions;</li> <li>It doesn't use the deprecated <code>UIKeyboardBoundsUserInfoKey</code>;</li> <li>It handles keyboard resize due to pressing the International key;</li> <li>Fixed memory leak by unregistering for keyboard events;</li> <li>All keyboard handling code is encapsulated in a separate class - <code>KBKeyboardHandler</code>;</li> <li>Flexibility - <code>KBKeyboardHandler</code> class may be easy extended / modified to better suit specific needs;</li> </ul> <p>Limitations:</p> <ul> <li>Works for iOS 4 and above, it needs small modifications to support older versions;</li> <li>It works for applications with a single <code>UIWindow</code>. If you use multiple UIWindows, you may need to modify <code>retrieveFrameFromNotification:</code> method.</li> </ul> <p>Usage:</p> <p>Include KBKeyboardHandler.h, KBKeyboardHandler.m and KBKeyboardHandlerDelegate.h in your project. Implement the <code>KBKeyboardHandlerDelegate</code> protocol in your view controller - it consists of a single method, which will be called when keyboard is shown, hidden or its size is changed. Instantiate the <code>KBKeyboardHandler</code> and set its delegate (typically self). See sample <code>MyViewController</code> below.</p> <p><strong>KBKeyboardHandler.h</strong>:</p> <pre><code>#import &lt;Foundation/Foundation.h&gt; #import &lt;UIKit/UIKit.h&gt; @protocol KBKeyboardHandlerDelegate; @interface KBKeyboardHandler : NSObject - (id)init; // Put 'weak' instead of 'assign' if you use ARC @property(nonatomic, assign) id&lt;KBKeyboardHandlerDelegate&gt; delegate; @property(nonatomic) CGRect frame; @end </code></pre> <p><strong>KBKeyboardHandler.m</strong>:</p> <pre><code>#import "KBKeyboardHandler.h" #import "KBKeyboardHandlerDelegate.h" @implementation KBKeyboardHandler - (id)init { self = [super init]; if (self) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; } return self; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; [super dealloc]; } @synthesize delegate; @synthesize frame; - (void)keyboardWillShow:(NSNotification *)notification { CGRect oldFrame = self.frame; [self retrieveFrameFromNotification:notification]; if (oldFrame.size.height != self.frame.size.height) { CGSize delta = CGSizeMake(self.frame.size.width - oldFrame.size.width, self.frame.size.height - oldFrame.size.height); if (self.delegate) [self notifySizeChanged:delta notification:notification]; } } - (void)keyboardWillHide:(NSNotification *)notification { if (self.frame.size.height &gt; 0.0) { [self retrieveFrameFromNotification:notification]; CGSize delta = CGSizeMake(-self.frame.size.width, -self.frame.size.height); if (self.delegate) [self notifySizeChanged:delta notification:notification]; } self.frame = CGRectZero; } - (void)retrieveFrameFromNotification:(NSNotification *)notification { CGRect keyboardRect; [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&amp;keyboardRect]; self.frame = [[UIApplication sharedApplication].keyWindow.rootViewController.view convertRect:keyboardRect fromView:nil]; } - (void)notifySizeChanged:(CGSize)delta notification:(NSNotification *)notification { NSDictionary *info = [notification userInfo]; UIViewAnimationOptions curve; [[info objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&amp;curve]; NSTimeInterval duration; [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&amp;duration]; void (^action)(void) = ^{ [self.delegate keyboardSizeChanged:delta]; }; [UIView animateWithDuration:duration delay:0.0 options:curve animations:action completion:nil]; } @end </code></pre> <p><strong>KBKeyboardHandlerDelegate.h</strong>:</p> <pre><code>@protocol KBKeyboardHandlerDelegate - (void)keyboardSizeChanged:(CGSize)delta; @end </code></pre> <p>Sample <strong>MyViewController.h</strong>:</p> <pre><code>@interface MyViewController : UIViewController&lt;KBKeyboardHandlerDelegate&gt; ... @end </code></pre> <p>Sample <strong>MyViewController.m</strong>:</p> <pre><code>@implementation MyViewController { KBKeyboardHandler *keyboard; } - (void)dealloc { keyboard.delegate = nil; [keyboard release]; [super dealloc]; } - (void)viewDidLoad { [super viewDidLoad]; keyboard = [[KBKeyboardHandler alloc] init]; keyboard.delegate = self; } - (void)viewDidUnload { [super viewDidUnload]; keyboard.delegate = nil; [keyboard release]; keyboard = nil; } - (void)keyboardSizeChanged:(CGSize)delta { // Resize / reposition your views here. All actions performed here // will appear animated. // delta is the difference between the previous size of the keyboard // and the new one. // For instance when the keyboard is shown, // delta may has width=768, height=264, // when the keyboard is hidden: width=-768, height=-264. // Use keyboard.frame.size to get the real keyboard size. // Sample: CGRect frame = self.view.frame; frame.size.height -= delta.height; self.view.frame = frame; } </code></pre> <p>UPDATE: Fixed iOS 7 warning, thanks @weienv.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload