Archive for juillet, 2009

[Cocoa] How to add a toolbar with button on top of a UITextView in order to add a dismiss button

The big problem with UITextView is there isn’t any native way to hide the keyboard once the input ended.
The following code describes a DissmisableTextView. This view extends UITextView adding on top of the keyboard associated with this UITextView a toolbar with a « Done » Button :

Here is the code :

//
//  DismissableTextView.h
//
//  A textView allowing to dismiss keyboard with a toolbar and a
//  Done button on top of the keyboard
//
//  Created by Vincent Demay on 02/07/09.
//
 
@interface DismissableTextView : UITextView {
  UIToolbar* keyboardToolbar;
}
- (void) keyboardWillShow:(NSNotification *)note;
- (void) dismissKeyboard; 
 
@end
 
//
//  DismissableTextView.m
//
//  Created by Vincent Demay on 02/07/09. /
// #import "DismissableTextView.h" 
 
@implementation DismissableTextView 
 
- (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
         //register a specific method on keyboard appearence
         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    }
    return self;
} 
 
- (void)keyboardWillShow:(NSNotification *)notification {
    for (UIWindow *keyboardWindow in [[UIApplication sharedApplication] windows]) {
         // Now iterating over each subview of the available windows
         for (UIView *keyboard in [keyboardWindow subviews]) {
             // Check to see if the description of the view we have referenced is UIKeyboard.
             // If so then we found the keyboard view that we were looking for.
             if([[keyboard description] hasPrefix:@"<UIKeyboard"] == YES) {
                  NSValue *v = [[notification userInfo] valueForKey:UIKeyboardBoundsUserInfoKey];
		  CGRect kbBounds = [v CGRectValue];
                  if(keyboardToolbar == nil) {
                      keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectZero];
       		      keyboardToolbar.barStyle = UIBarStyleBlackTranslucent;
		      UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleBordered target:self action:@selector(dismissKeyboard)];
		      UIBarButtonItem *flex = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
		      NSArray *items = [[NSArray alloc] initWithObjects:flex, barButtonItem, nil];
		      [keyboardToolbar setItems:items];
		      [items release];
                  }
                  [keyboardToolbar removeFromSuperview];
		  keyboardToolbar.frame = CGRectMake(0, 0, kbBounds.size.width, 30);
		  [keyboard addSubview:keyboardToolbar];
		  keyboard.bounds = CGRectMake(kbBounds.origin.x, kbBounds.origin.y, kbBounds.size.width, kbBounds.size.height + 60);
                  for(UIView* subKeyboard in [keyboard subviews]) {
		      if([[subKeyboard description] hasPrefix:@"<UIKeyboardImpl"] == YES) {
                          subKeyboard.bounds = CGRectMake(kbBounds.origin.x, kbBounds.origin.y - 30, kbBounds.size.width, kbBounds.size.height);
		      }
                  }
              }
          }
     }
} 
 
- (void) dismissKeyboard {
    [self resignFirstResponder];
} 
 
- (void)dealloc {
     [super dealloc];
}
 
@end