From 383478ef34703312978f580b5f362ea3f59f3062 Mon Sep 17 00:00:00 2001 From: Michael Tyson Date: Tue, 12 Mar 2013 12:28:56 +1100 Subject: [PATCH] Implemented automatic "next" buttons on keyboard to switch text fields --- .../FirstViewController.h | 7 +- .../FirstViewController.m | 45 ----- .../SecondViewController.h | 2 +- .../SecondViewController.m | 9 +- .../en.lproj/FirstView.xib | 140 +++++----------- TPKeyboardAvoidingScrollView.h | 13 +- TPKeyboardAvoidingScrollView.m | 123 ++++++++++++-- TPKeyboardAvoidingTableView.h | 11 +- TPKeyboardAvoidingTableView.m | 157 +++++++++++++++--- 9 files changed, 294 insertions(+), 213 deletions(-) diff --git a/TPKeyboardAvoidingSample/FirstViewController.h b/TPKeyboardAvoidingSample/FirstViewController.h index ae5046cd..862065a7 100644 --- a/TPKeyboardAvoidingSample/FirstViewController.h +++ b/TPKeyboardAvoidingSample/FirstViewController.h @@ -10,11 +10,6 @@ @class TPKeyboardAvoidingScrollView; -@interface FirstViewController : UIViewController +@interface FirstViewController : UIViewController @property (nonatomic, retain) IBOutlet TPKeyboardAvoidingScrollView *scrollView; -@property (nonatomic, retain) IBOutlet UITextField *txtIggle; -@property (nonatomic, retain) IBOutlet UITextField *txtNiggle; -@property (nonatomic, retain) IBOutlet UITextField *txtOggle; -@property (nonatomic, retain) IBOutlet UITextField *txtBogle; -@property (nonatomic, retain) IBOutlet UITextField *txtSplat; @end diff --git a/TPKeyboardAvoidingSample/FirstViewController.m b/TPKeyboardAvoidingSample/FirstViewController.m index 0ec263e5..da813018 100644 --- a/TPKeyboardAvoidingSample/FirstViewController.m +++ b/TPKeyboardAvoidingSample/FirstViewController.m @@ -11,12 +11,6 @@ @implementation FirstViewController @synthesize scrollView; -@synthesize txtIggle; -@synthesize txtNiggle; -@synthesize txtOggle; -@synthesize txtBogle; -@synthesize txtSplat; - // Implement viewDidLoad to do additional setup after loading the view, typically from a nib. - (void)viewDidLoad @@ -50,11 +44,6 @@ - (void)didReceiveMemoryWarning - (void)viewDidUnload { [self setScrollView:nil]; - [self setTxtIggle:nil]; - [self setTxtNiggle:nil]; - [self setTxtOggle:nil]; - [self setTxtBogle:nil]; - [self setTxtSplat:nil]; [super viewDidUnload]; // Release any retained subviews of the main view. @@ -65,41 +54,7 @@ - (void)viewDidUnload - (void)dealloc { [scrollView release]; - [txtIggle release]; - [txtNiggle release]; - [txtOggle release]; - [txtBogle release]; - [txtSplat release]; [super dealloc]; } --(BOOL)textFieldShouldReturn:(UITextField *)textField { - if (textField == txtIggle) { - [txtNiggle becomeFirstResponder]; - } - - else if (textField == txtNiggle) { - [txtOggle becomeFirstResponder]; - } - - else if (textField == txtOggle) { - [txtBogle becomeFirstResponder]; - } - - else if (textField == txtBogle) { - [txtSplat becomeFirstResponder]; - } - else{ - [textField resignFirstResponder]; - } - - - return YES; -} - --(void)textFieldDidBeginEditing:(UITextField *)textField -{ - [scrollView adjustOffsetToIdealIfNeeded]; -} - @end diff --git a/TPKeyboardAvoidingSample/SecondViewController.h b/TPKeyboardAvoidingSample/SecondViewController.h index 739f5541..21adc46f 100644 --- a/TPKeyboardAvoidingSample/SecondViewController.h +++ b/TPKeyboardAvoidingSample/SecondViewController.h @@ -9,5 +9,5 @@ #import -@interface SecondViewController : UITableViewController +@interface SecondViewController : UITableViewController @end diff --git a/TPKeyboardAvoidingSample/SecondViewController.m b/TPKeyboardAvoidingSample/SecondViewController.m index b77c434b..98c1cace 100644 --- a/TPKeyboardAvoidingSample/SecondViewController.m +++ b/TPKeyboardAvoidingSample/SecondViewController.m @@ -99,10 +99,10 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; UITextField *textField = [[[UITextField alloc] initWithFrame:CGRectMake(0, 0, 150, 30)] autorelease]; - textField.delegate = self; textField.returnKeyType = UIReturnKeyDone; textField.borderStyle = UITextBorderStyleRoundedRect; cell.accessoryView = textField; + cell.selectionStyle = UITableViewCellSelectionStyleNone; } cell.textLabel.text = [NSString stringWithFormat:@"Order %d", indexPath.row]; @@ -111,11 +111,4 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N return cell; } -#pragma mark - Text field delegate - --(BOOL)textFieldShouldReturn:(UITextField *)textField { - [textField resignFirstResponder]; - return YES; -} - @end \ No newline at end of file diff --git a/TPKeyboardAvoidingSample/en.lproj/FirstView.xib b/TPKeyboardAvoidingSample/en.lproj/FirstView.xib index ed526077..8437a843 100644 --- a/TPKeyboardAvoidingSample/en.lproj/FirstView.xib +++ b/TPKeyboardAvoidingSample/en.lproj/FirstView.xib @@ -51,6 +51,7 @@ 292 {{20, 30}, {280, 31}} + NO YES @@ -87,6 +88,7 @@ 292 {{20, 281}, {280, 31}} + NO YES @@ -114,6 +116,7 @@ 292 {{20, 337}, {280, 37}} + NO IBCocoaTouchFramework @@ -121,7 +124,7 @@ 0 1 Do A Thing - + 3 MQA @@ -150,6 +153,7 @@ 292 {{20, 94}, {280, 31}} + NO YES @@ -177,6 +181,7 @@ 292 {{20, 156}, {280, 31}} + NO YES @@ -204,6 +209,7 @@ 292 {{20, 218}, {280, 31}} + NO YES @@ -231,7 +237,7 @@ 292 {{20, 400}, {280, 31}} - + NO YES IBCocoaTouchFramework @@ -258,6 +264,7 @@ 292 {{20, 500}, {280, 31}} + NO YES @@ -283,6 +290,7 @@ {320, 411} + YES YES @@ -291,12 +299,9 @@ {{0, 20}, {320, 411}} + - - 1 - MCAwIDAgMAA - groupTableViewBackgroundColor - + IBCocoaTouchFramework @@ -321,94 +326,6 @@ 21 - - - txtIggle - - - - 22 - - - - txtNiggle - - - - 23 - - - - txtOggle - - - - 24 - - - - txtBogle - - - - 25 - - - - txtSplat - - - - 26 - - - - delegate - - - - 13 - - - - delegate - - - - 14 - - - - delegate - - - - 16 - - - - delegate - - - - 18 - - - - delegate - - - - 20 - - - - delegate - - - - 28 - @@ -552,7 +469,38 @@ 29 - + + + YES + + FirstViewController + UIViewController + + scrollView + TPKeyboardAvoidingScrollView + + + scrollView + + scrollView + TPKeyboardAvoidingScrollView + + + + IBProjectSource + ./Classes/FirstViewController.h + + + + TPKeyboardAvoidingScrollView + UIScrollView + + IBProjectSource + ./Classes/TPKeyboardAvoidingScrollView.h + + + + 0 IBCocoaTouchFramework diff --git a/TPKeyboardAvoidingScrollView.h b/TPKeyboardAvoidingScrollView.h index 30c365e2..59c2ed42 100755 --- a/TPKeyboardAvoidingScrollView.h +++ b/TPKeyboardAvoidingScrollView.h @@ -7,14 +7,7 @@ #import -@interface TPKeyboardAvoidingScrollView : UIScrollView { - UIEdgeInsets _priorInset; - BOOL _priorInsetSaved; - BOOL _keyboardVisible; - CGRect _keyboardRect; - CGSize _originalContentSize; - CGPoint _originalContentOffset; -} - -- (void)adjustOffsetToIdealIfNeeded; +@interface TPKeyboardAvoidingScrollView : UIScrollView +- (BOOL)focusNextTextField; +- (void)scrollToActiveTextField; @end diff --git a/TPKeyboardAvoidingScrollView.m b/TPKeyboardAvoidingScrollView.m index d62e287c..bd831bc9 100644 --- a/TPKeyboardAvoidingScrollView.m +++ b/TPKeyboardAvoidingScrollView.m @@ -9,7 +9,14 @@ #define _UIKeyboardFrameEndUserInfoKey (&UIKeyboardFrameEndUserInfoKey != NULL ? UIKeyboardFrameEndUserInfoKey : @"UIKeyboardBoundsUserInfoKey") -@interface TPKeyboardAvoidingScrollView () +@interface TPKeyboardAvoidingScrollView () { + UIEdgeInsets _priorInset; + BOOL _priorInsetSaved; + BOOL _keyboardVisible; + CGRect _keyboardRect; + CGSize _originalContentSize; + CGPoint _originalContentOffset; +} - (UIView*)findFirstResponderBeneathView:(UIView*)view; - (UIEdgeInsets)contentInsetForKeyboard; - (CGFloat)idealOffsetForView:(UIView *)view withSpace:(CGFloat)space; @@ -18,6 +25,8 @@ - (CGRect)keyboardRect; @implementation TPKeyboardAvoidingScrollView +#pragma mark - Setup/Teardown + - (void)setup { _priorInsetSaved = NO; if ( CGSizeEqualToSize(self.contentSize, CGSizeZero) ) { @@ -69,6 +78,8 @@ -(void)setContentSize:(CGSize)contentSize { } } +#pragma mark - Responders, events + - (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { [[self findFirstResponderBeneathView:self] resignFirstResponder]; [super touchesEnded:touches withEvent:event]; @@ -120,6 +131,60 @@ - (void)keyboardWillHide:(NSNotification*)notification { [UIView commitAnimations]; } +-(BOOL)textFieldShouldReturn:(UITextField *)textField { + if ( ![self focusNextTextField] ) { + [textField resignFirstResponder]; + } + return YES; +} + +-(void)textFieldDidBeginEditing:(UITextField *)textField { + [self scrollToActiveTextField]; +} + +-(void)textViewDidBeginEditing:(UITextView *)textView { + [self scrollToActiveTextField]; +} + +-(void)layoutSubviews { + [super layoutSubviews]; + [self initializeViewsBeneathView:self]; +} + +#pragma mark - Utilities + +- (BOOL)focusNextTextField { + UIView *firstResponder = [self findFirstResponderBeneathView:self]; + if ( !firstResponder ) { + return NO; + } + + CGFloat minY = CGFLOAT_MAX; + UIView *view = nil; + [self findTextFieldAfterTextField:firstResponder beneathView:self minY:&minY foundView:&view]; + + if ( view ) { + [view becomeFirstResponder]; + return YES; + } + + return NO; +} + +-(void)scrollToActiveTextField { + if ( !_keyboardVisible ) return; + + CGFloat visibleSpace = self.bounds.size.height - self.contentInset.top - self.contentInset.bottom; + + CGPoint idealOffset = CGPointMake(0, [self idealOffsetForView:[self findFirstResponderBeneathView:self] withSpace:visibleSpace]); + + [self setContentOffset:idealOffset animated:YES]; + + _originalContentOffset = self.contentOffset; +} + +#pragma mark - Helpers + - (UIView*)findFirstResponderBeneathView:(UIView*)view { // Search recursively for first responder for ( UIView *childView in view.subviews ) { @@ -130,6 +195,33 @@ - (UIView*)findFirstResponderBeneathView:(UIView*)view { return nil; } +- (void)findTextFieldAfterTextField:(UIView*)priorTextField beneathView:(UIView*)view minY:(CGFloat*)minY foundView:(UIView**)foundView { + // Search recursively for text field or text view below priorTextField + CGFloat priorFieldOffset = CGRectGetMinY([self convertRect:priorTextField.frame fromView:priorTextField.superview]); + for ( UIView *childView in view.subviews ) { + if ( childView.hidden ) continue; + if ( ([childView isKindOfClass:[UITextField class]] || [childView isKindOfClass:[UITextView class]]) ) { + CGRect frame = [self convertRect:childView.frame fromView:view]; + if ( childView != priorTextField && CGRectGetMinY(frame) >= priorFieldOffset && CGRectGetMinY(frame) < *minY ) { + *minY = CGRectGetMinY(frame); + *foundView = childView; + } + } else { + [self findTextFieldAfterTextField:priorTextField beneathView:childView minY:minY foundView:foundView]; + } + } +} + +- (void)initializeViewsBeneathView:(UIView*)view { + for ( UIView *childView in view.subviews ) { + if ( ([childView isKindOfClass:[UITextField class]] || [childView isKindOfClass:[UITextView class]]) ) { + [self initializeView:childView]; + } else { + [self initializeViewsBeneathView:childView]; + } + } +} + - (UIEdgeInsets)contentInsetForKeyboard { UIEdgeInsets newInset = self.contentInset; CGRect keyboardRect = [self keyboardRect]; @@ -165,18 +257,6 @@ -(CGFloat)idealOffsetForView:(UIView *)view withSpace:(CGFloat)space { return offset; } --(void)adjustOffsetToIdealIfNeeded { - - // Only do this if the keyboard is already visible - if ( !_keyboardVisible ) return; - - CGFloat visibleSpace = self.bounds.size.height - self.contentInset.top - self.contentInset.bottom; - - CGPoint idealOffset = CGPointMake(0, [self idealOffsetForView:[self findFirstResponderBeneathView:self] withSpace:visibleSpace]); - - [self setContentOffset:idealOffset animated:YES]; -} - - (CGRect)keyboardRect { CGRect keyboardRect = [self convertRect:_keyboardRect fromView:nil]; if ( keyboardRect.origin.y == 0 ) { @@ -186,4 +266,21 @@ - (CGRect)keyboardRect { return keyboardRect; } +- (void)initializeView:(UIView*)view { + if ( ([view isKindOfClass:[UITextField class]] || [view isKindOfClass:[UITextView class]]) && (![(id)view delegate] || [(id)view delegate] == self) ) { + [(id)view setDelegate:self]; + + if ( [view isKindOfClass:[UITextField class]] ) { + UIView *otherView = nil; + CGFloat minY = CGFLOAT_MAX; + [self findTextFieldAfterTextField:view beneathView:self minY:&minY foundView:&otherView]; + if ( otherView ) { + ((UITextField*)view).returnKeyType = UIReturnKeyNext; + } else { + ((UITextField*)view).returnKeyType = UIReturnKeyDone; + } + } + } +} + @end diff --git a/TPKeyboardAvoidingTableView.h b/TPKeyboardAvoidingTableView.h index 743f531c..7f2949c7 100644 --- a/TPKeyboardAvoidingTableView.h +++ b/TPKeyboardAvoidingTableView.h @@ -7,12 +7,7 @@ #import -@interface TPKeyboardAvoidingTableView : UITableView { - UIEdgeInsets _priorInset; - BOOL _priorInsetSaved; - BOOL _keyboardVisible; - CGRect _keyboardRect; -} - -- (void)adjustOffsetToIdealIfNeeded; +@interface TPKeyboardAvoidingTableView : UITableView +- (BOOL)focusNextTextField; +- (void)scrollToActiveTextField; @end diff --git a/TPKeyboardAvoidingTableView.m b/TPKeyboardAvoidingTableView.m index 6c8fd1fc..ad8c0382 100644 --- a/TPKeyboardAvoidingTableView.m +++ b/TPKeyboardAvoidingTableView.m @@ -9,7 +9,14 @@ #define _UIKeyboardFrameEndUserInfoKey (&UIKeyboardFrameEndUserInfoKey != NULL ? UIKeyboardFrameEndUserInfoKey : @"UIKeyboardBoundsUserInfoKey") -@interface TPKeyboardAvoidingTableView () +@interface TPKeyboardAvoidingTableView () { + UIEdgeInsets _priorInset; + BOOL _priorInsetSaved; + BOOL _keyboardVisible; + CGRect _keyboardRect; + CGSize _originalContentSize; + CGPoint _originalContentOffset; +} - (UIView*)findFirstResponderBeneathView:(UIView*)view; - (UIEdgeInsets)contentInsetForKeyboard; - (CGFloat)idealOffsetForView:(UIView *)view withSpace:(CGFloat)space; @@ -18,7 +25,10 @@ - (CGRect)keyboardRect; @implementation TPKeyboardAvoidingTableView +#pragma mark - Setup/Teardown + - (void)setup { + _priorInsetSaved = NO; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; } @@ -29,43 +39,48 @@ -(id)initWithFrame:(CGRect)frame { return self; } --(id)initWithFrame:(CGRect)frame style:(UITableViewStyle)style { - if ( !(self = [super initWithFrame:frame style:style]) ) return nil; +-(void)awakeFromNib { [self setup]; - return self; -} - --(id)initWithCoder:(NSCoder *)aDecoder { - if ( !(self = [super initWithCoder:aDecoder]) ) return nil; - [self setup]; - return self; } -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; -#if !__has_feature(objc_arc) +#if !__has_feature(objc_arc) [super dealloc]; #endif } -(void)setFrame:(CGRect)frame { [super setFrame:frame]; + + CGSize contentSize = _originalContentSize; + contentSize.width = MAX(contentSize.width, self.frame.size.width); + contentSize.height = MAX(contentSize.height, self.frame.size.height); + [super setContentSize:contentSize]; + if ( _keyboardVisible ) { self.contentInset = [self contentInsetForKeyboard]; } } -(void)setContentSize:(CGSize)contentSize { + _originalContentSize = contentSize; + + contentSize.width = MAX(contentSize.width, self.frame.size.width); + contentSize.height = MAX(contentSize.height, self.frame.size.height); [super setContentSize:contentSize]; + if ( _keyboardVisible ) { self.contentInset = [self contentInsetForKeyboard]; } } +#pragma mark - Responders, events + - (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { [[self findFirstResponderBeneathView:self] resignFirstResponder]; [super touchesEnded:touches withEvent:event]; -} +} - (void)keyboardWillShow:(NSNotification*)notification { _keyboardRect = [[[notification userInfo] objectForKey:_UIKeyboardFrameEndUserInfoKey] CGRectValue]; @@ -77,6 +92,8 @@ - (void)keyboardWillShow:(NSNotification*)notification { return; } + _originalContentOffset = self.contentOffset; + if (!_priorInsetSaved) { _priorInset = self.contentInset; _priorInsetSaved = YES; @@ -88,8 +105,8 @@ - (void)keyboardWillShow:(NSNotification*)notification { [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]]; self.contentInset = [self contentInsetForKeyboard]; - [self setContentOffset:CGPointMake(self.contentOffset.x, - [self idealOffsetForView:firstResponder withSpace:[self keyboardRect].origin.y - self.bounds.origin.y]) + [self setContentOffset:CGPointMake(self.contentOffset.x, + [self idealOffsetForView:firstResponder withSpace:[self keyboardRect].origin.y - self.bounds.origin.y]) animated:YES]; [self setScrollIndicatorInsets:self.contentInset]; @@ -105,11 +122,66 @@ - (void)keyboardWillHide:(NSNotification*)notification { [UIView setAnimationCurve:[[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]]; [UIView setAnimationDuration:[[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]]; self.contentInset = _priorInset; + self.contentOffset = _originalContentOffset; [self setScrollIndicatorInsets:self.contentInset]; _priorInsetSaved = NO; [UIView commitAnimations]; } +-(BOOL)textFieldShouldReturn:(UITextField *)textField { + if ( ![self focusNextTextField] ) { + [textField resignFirstResponder]; + } + return YES; +} + +-(void)textFieldDidBeginEditing:(UITextField *)textField { + [self scrollToActiveTextField]; +} + +-(void)textViewDidBeginEditing:(UITextView *)textView { + [self scrollToActiveTextField]; +} + +-(void)layoutSubviews { + [super layoutSubviews]; + [self initializeViewsBeneathView:self]; +} + +#pragma mark - Utilities + +- (BOOL)focusNextTextField { + UIView *firstResponder = [self findFirstResponderBeneathView:self]; + if ( !firstResponder ) { + return NO; + } + + CGFloat minY = CGFLOAT_MAX; + UIView *view = nil; + [self findTextFieldAfterTextField:firstResponder beneathView:self minY:&minY foundView:&view]; + + if ( view ) { + [view becomeFirstResponder]; + return YES; + } + + return NO; +} + +-(void)scrollToActiveTextField { + if ( !_keyboardVisible ) return; + + CGFloat visibleSpace = self.bounds.size.height - self.contentInset.top - self.contentInset.bottom; + + CGPoint idealOffset = CGPointMake(0, [self idealOffsetForView:[self findFirstResponderBeneathView:self] withSpace:visibleSpace]); + + [self setContentOffset:idealOffset animated:YES]; + + _originalContentOffset = self.contentOffset; +} + +#pragma mark - Helpers + - (UIView*)findFirstResponderBeneathView:(UIView*)view { // Search recursively for first responder for ( UIView *childView in view.subviews ) { @@ -120,6 +192,33 @@ - (UIView*)findFirstResponderBeneathView:(UIView*)view { return nil; } +- (void)findTextFieldAfterTextField:(UIView*)priorTextField beneathView:(UIView*)view minY:(CGFloat*)minY foundView:(UIView**)foundView { + // Search recursively for text field or text view below priorTextField + CGFloat priorFieldOffset = CGRectGetMinY([self convertRect:priorTextField.frame fromView:priorTextField.superview]); + for ( UIView *childView in view.subviews ) { + if ( childView.hidden ) continue; + if ( ([childView isKindOfClass:[UITextField class]] || [childView isKindOfClass:[UITextView class]]) ) { + CGRect frame = [self convertRect:childView.frame fromView:view]; + if ( childView != priorTextField && CGRectGetMinY(frame) >= priorFieldOffset && CGRectGetMinY(frame) < *minY ) { + *minY = CGRectGetMinY(frame); + *foundView = childView; + } + } else { + [self findTextFieldAfterTextField:priorTextField beneathView:childView minY:minY foundView:foundView]; + } + } +} + +- (void)initializeViewsBeneathView:(UIView*)view { + for ( UIView *childView in view.subviews ) { + if ( ([childView isKindOfClass:[UITextField class]] || [childView isKindOfClass:[UITextView class]]) ) { + [self initializeView:childView]; + } else { + [self initializeViewsBeneathView:childView]; + } + } +} + - (UIEdgeInsets)contentInsetForKeyboard { UIEdgeInsets newInset = self.contentInset; CGRect keyboardRect = [self keyboardRect]; @@ -155,18 +254,6 @@ -(CGFloat)idealOffsetForView:(UIView *)view withSpace:(CGFloat)space { return offset; } --(void)adjustOffsetToIdealIfNeeded { - - // Only do this if the keyboard is already visible - if ( !_keyboardVisible ) return; - - CGFloat visibleSpace = self.bounds.size.height - self.contentInset.top - self.contentInset.bottom; - - CGPoint idealOffset = CGPointMake(0, [self idealOffsetForView:[self findFirstResponderBeneathView:self] withSpace:visibleSpace]); - - [self setContentOffset:idealOffset animated:YES]; -} - - (CGRect)keyboardRect { CGRect keyboardRect = [self convertRect:_keyboardRect fromView:nil]; if ( keyboardRect.origin.y == 0 ) { @@ -176,4 +263,22 @@ - (CGRect)keyboardRect { return keyboardRect; } +- (void)initializeView:(UIView*)view { + if ( ([view isKindOfClass:[UITextField class]] || [view isKindOfClass:[UITextView class]]) && (![(id)view delegate] || [(id)view delegate] == self) ) { + [(id)view setDelegate:self]; + + if ( [view isKindOfClass:[UITextField class]] ) { + UIView *otherView = nil; + CGFloat minY = CGFLOAT_MAX; + [self findTextFieldAfterTextField:view beneathView:self minY:&minY foundView:&otherView]; + + if ( otherView ) { + ((UITextField*)view).returnKeyType = UIReturnKeyNext; + } else { + ((UITextField*)view).returnKeyType = UIReturnKeyDone; + } + } + } +} + @end