From 5782c972735fe72960c95389b3c4c2176c951a23 Mon Sep 17 00:00:00 2001 From: Emil Date: Thu, 2 Apr 2015 11:10:23 +0300 Subject: [PATCH 01/13] - removeTextFieldView in IQKeyboardReturnKeyHandler has been fixed --- IQKeyBoardManager/IQKeyboardReturnKeyHandler.m | 2 +- IQKeybordManagerSwift/IQKeyboardReturnKeyHandler.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/IQKeyBoardManager/IQKeyboardReturnKeyHandler.m b/IQKeyBoardManager/IQKeyboardReturnKeyHandler.m index 94f69e8..8aed7ff 100644 --- a/IQKeyBoardManager/IQKeyboardReturnKeyHandler.m +++ b/IQKeyBoardManager/IQKeyboardReturnKeyHandler.m @@ -92,7 +92,7 @@ NSString *const kIQTextFieldReturnKeyType = @"kIQTextFieldReturnKeyType"; { textField.keyboardType = [dict[kIQTextFieldReturnKeyType] integerValue]; textField.delegate = dict[kIQTextFieldDelegate]; - [textFieldInfoCache removeObject:textField]; + [textFieldInfoCache removeObject:dict]; } } diff --git a/IQKeybordManagerSwift/IQKeyboardReturnKeyHandler.swift b/IQKeybordManagerSwift/IQKeyboardReturnKeyHandler.swift index c9d4824..5920fc2 100644 --- a/IQKeybordManagerSwift/IQKeyboardReturnKeyHandler.swift +++ b/IQKeybordManagerSwift/IQKeyboardReturnKeyHandler.swift @@ -149,7 +149,7 @@ class IQKeyboardReturnKeyHandler: NSObject , UITextFieldDelegate, UITextViewDele textView.delegate = dict[kIQTextFieldDelegate] as UITextViewDelegate? } - textFieldInfoCache.removeObject(view) + textFieldInfoCache.removeObject(dict) } } From 7cc417526670ba303f284ca69193cf02db1fc5e7 Mon Sep 17 00:00:00 2001 From: hackiftekhar Date: Tue, 7 Apr 2015 11:51:44 +0530 Subject: [PATCH 02/13] Added Xcode 5.0 compatibility --- .../IQKeyboardManagerConstantsInternal.h | 8 ++++---- IQKeyBoardManager/IQKeyboardManager.h | 6 +++++- IQKeyBoardManager/IQKeyboardManager.m | 15 ++++++++++++++- .../IQKeyboardReturnKeyHandler.m | 5 +++++ .../IQSegmentedNextPrevious.h | 1 - IQKeyBoardManager/IQToolbar/IQToolbar.m | 5 ++++- KeyboardTextFieldDemo/.DS_Store | Bin 10244 -> 15364 bytes .../IQDropDownTextField/IQDropDownTextField.m | 2 +- .../SettingsViewController.m | 8 ++++++++ .../TextFieldViewController.m | 4 ++++ 10 files changed, 45 insertions(+), 9 deletions(-) diff --git a/IQKeyBoardManager/Constants/IQKeyboardManagerConstantsInternal.h b/IQKeyBoardManager/Constants/IQKeyboardManagerConstantsInternal.h index d75a3ed..b7083b7 100644 --- a/IQKeyBoardManager/Constants/IQKeyboardManagerConstantsInternal.h +++ b/IQKeyBoardManager/Constants/IQKeyboardManagerConstantsInternal.h @@ -24,16 +24,16 @@ #ifndef IQKeyboardManagerConstantsInternal_h #define IQKeyboardManagerConstantsInternal_h -//Xcode 4.6 or less compilation check +//Xcode 5 compatibility check #ifdef NSFoundationVersionNumber_iOS_6_1 #define IQ_IS_IOS7_OR_GREATER (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) - #define IQ_IS_XCODE_5_1_OR_GREATER 1 + #define IQ_IS_XCODE_5_OR_GREATER 1 #else #define IQ_IS_IOS7_OR_GREATER NO - #define IQ_IS_XCODE_5_1_OR_GREATER 0 + #define IQ_IS_XCODE_5_OR_GREATER 0 #endif -//Xcode 5.1 or less compilation check +//Xcode 6 compatibility check #ifdef NSFoundationVersionNumber_iOS_7_1 #define IQ_IS_IOS8_OR_GREATER (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1) #define IQ_IS_XCODE_6_0_OR_GREATER 1 diff --git a/IQKeyBoardManager/IQKeyboardManager.h b/IQKeyBoardManager/IQKeyboardManager.h index 44629d3..92979e6 100755 --- a/IQKeyBoardManager/IQKeyboardManager.h +++ b/IQKeyBoardManager/IQKeyboardManager.h @@ -104,12 +104,16 @@ extern NSInteger const kIQPreviousNextButtonToolbarTag; */ @property(nonatomic, assign) IQAutoToolbarManageBehaviour toolbarManageBehaviour; +#if IQ_IS_XCODE_5_OR_GREATER + /** @property shouldToolbarUsesTextFieldTintColor @abstract If YES, then uses textField's tintColor property for IQToolbar, otherwise tint color is black. Default is NO. */ -@property(nonatomic, assign) BOOL shouldToolbarUsesTextFieldTintColor NS_AVAILABLE_IOS(7_0); +@property(nonatomic, assign) BOOL shouldToolbarUsesTextFieldTintColor NS_AVAILABLE_IOS(7_0); + +#endif /** @property shouldShowTextFieldPlaceholder diff --git a/IQKeyBoardManager/IQKeyboardManager.m b/IQKeyBoardManager/IQKeyboardManager.m index 50d0ab3..ffc2bae 100755 --- a/IQKeyBoardManager/IQKeyboardManager.m +++ b/IQKeyBoardManager/IQKeyboardManager.m @@ -46,6 +46,9 @@ void _IQShowLog(NSString *logString); @interface IQKeyboardManager() +//Compatibility +@property(nonatomic, assign) BOOL shouldToolbarUsesTextFieldTintColor; + // Private helper methods - (void)adjustFrame; @@ -1252,7 +1255,11 @@ void _IQShowLog(NSString *logString); // If only one object is found, then adding only Done button. if (siblings.count==1) { - UITextField *textField = [siblings firstObject]; + UITextField *textField = nil; + + if ([siblings count]) + textField = [siblings objectAtIndex:0]; + //Either there is no inputAccessoryView or if accessoryView is not appropriate for current situation(There is Previous/Next/Done toolbar). if (![textField inputAccessoryView] || ([[textField inputAccessoryView] tag] == kIQPreviousNextButtonToolbarTag)) @@ -1282,9 +1289,12 @@ void _IQShowLog(NSString *logString); { toolbar.barStyle = UIBarStyleDefault; +#if IQ_IS_XCODE_5_OR_GREATER //Setting toolbar tintColor // (Enhancement ID: #30) if (_shouldToolbarUsesTextFieldTintColor && [toolbar respondsToSelector:@selector(tintColor)]) [toolbar setTintColor:[textField tintColor]]; +#endif + } break; } @@ -1336,9 +1346,12 @@ void _IQShowLog(NSString *logString); { toolbar.barStyle = UIBarStyleDefault; +#if IQ_IS_XCODE_5_OR_GREATER //Setting toolbar tintColor // (Enhancement ID: #30) if (_shouldToolbarUsesTextFieldTintColor && [toolbar respondsToSelector:@selector(tintColor)]) [toolbar setTintColor:[textField tintColor]]; +#endif + } break; } diff --git a/IQKeyBoardManager/IQKeyboardReturnKeyHandler.m b/IQKeyBoardManager/IQKeyboardReturnKeyHandler.m index 94f69e8..04bbf51 100644 --- a/IQKeyBoardManager/IQKeyboardReturnKeyHandler.m +++ b/IQKeyBoardManager/IQKeyboardReturnKeyHandler.m @@ -23,6 +23,7 @@ #import "IQKeyboardReturnKeyHandler.h" +#import "IQKeyboardManagerConstantsInternal.h" #import "IQUIView+Hierarchy.h" #import "IQNSArray+Sort.h" @@ -329,6 +330,8 @@ NSString *const kIQTextFieldReturnKeyType = @"kIQTextFieldReturnKeyType"; [self.delegate textViewDidChangeSelection:textView]; } +#if IQ_IS_XCODE_5_OR_GREATER + - (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange { if ([self.delegate respondsToSelector:@selector(textView:shouldInteractWithURL:inRange:)]) @@ -345,6 +348,8 @@ NSString *const kIQTextFieldReturnKeyType = @"kIQTextFieldReturnKeyType"; return YES; } +#endif + -(void)dealloc { for (NSDictionary *dict in textFieldInfoCache) diff --git a/IQKeyBoardManager/IQSegmentedNextPrevious/IQSegmentedNextPrevious.h b/IQKeyBoardManager/IQSegmentedNextPrevious/IQSegmentedNextPrevious.h index 4e6e562..ddc78d9 100644 --- a/IQKeyBoardManager/IQSegmentedNextPrevious/IQSegmentedNextPrevious.h +++ b/IQKeyBoardManager/IQSegmentedNextPrevious/IQSegmentedNextPrevious.h @@ -35,7 +35,6 @@ @abstract Custom SegmentedControl for Previous/Next button. */ -NS_CLASS_DEPRECATED_IOS(2_0, 7_0, "Deprecated for iOS 7") @interface IQSegmentedNextPrevious : UISegmentedControl /** diff --git a/IQKeyBoardManager/IQToolbar/IQToolbar.m b/IQKeyBoardManager/IQToolbar/IQToolbar.m index 91e330e..81c7b24 100644 --- a/IQKeyBoardManager/IQToolbar/IQToolbar.m +++ b/IQKeyBoardManager/IQToolbar/IQToolbar.m @@ -36,11 +36,14 @@ [super initialize]; [[self appearance] setTintColor:nil]; + +#if IQ_IS_XCODE_5_OR_GREATER if ([[self appearance] respondsToSelector:@selector(setBarTintColor:)]) { [[self appearance] setBarTintColor:nil]; } - +#endif + [[self appearance] setBackgroundColor:nil]; } diff --git a/KeyboardTextFieldDemo/.DS_Store b/KeyboardTextFieldDemo/.DS_Store index bc69393c4273ea73095ee85279d0caa9c365e9ee..474fa8368bf9ed30737992d543e49e3f0a5193aa 100644 GIT binary patch delta 68 zcmZn(XsOr`Ey&E0z&|-o(3RP0UCrbVf;N1)`6(_br6tJ>3>P6no=mI?lP?M>Z;lgM UCc4>C;u!np0EzAF8ylKg05p3TJpcdz delta 54 zcmZpvXbIR5Ey&D#WYOd}L04vHqotES2-@)F=BK!%l$InjFkFNPc`~sCOui_jyg5#2 GnJ54sUK3;h diff --git a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/IQDropDownTextField/IQDropDownTextField.m b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/IQDropDownTextField/IQDropDownTextField.m index aeeb5ee..dc74cdc 100755 --- a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/IQDropDownTextField/IQDropDownTextField.m +++ b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/IQDropDownTextField/IQDropDownTextField.m @@ -399,7 +399,7 @@ -(NSDateComponents *)dateComponents { - return [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:self.date]; + return [[NSCalendar currentCalendar] components:kCFCalendarUnitDay | kCFCalendarUnitMonth | kCFCalendarUnitYear fromDate:self.date]; } - (NSInteger)year { return [[self dateComponents] year]; } diff --git a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/SettingsViewController.m b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/SettingsViewController.m index d6eb375..a673f1e 100644 --- a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/SettingsViewController.m +++ b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/SettingsViewController.m @@ -99,7 +99,9 @@ - (void)shouldToolbarUsesTextFieldTintColorAction:(UISwitch *)sender { +#if IQ_IS_XCODE_5_OR_GREATER [[IQKeyboardManager sharedManager] setShouldToolbarUsesTextFieldTintColor:sender.on]; +#endif } - (void)shouldShowTextFieldPlaceholder:(UISwitch *)sender @@ -275,7 +277,13 @@ SwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SwitchTableViewCell class]) forIndexPath:indexPath]; cell.labelTitle.text = keyboardManagerProperties[indexPath.section][indexPath.row]; cell.labelSubtitle.text = keyboardManagerPropertyDetails[indexPath.section][indexPath.row]; + +#if IQ_IS_XCODE_5_OR_GREATER cell.switchEnable.on = [[IQKeyboardManager sharedManager] shouldToolbarUsesTextFieldTintColor]; +#else + cell.switchEnable.on = NO; + cell.switchEnable.enabled = NO; +#endif [cell.switchEnable removeTarget:nil action:NULL forControlEvents:UIControlEventAllEvents]; [cell.switchEnable addTarget:self action:@selector(shouldToolbarUsesTextFieldTintColorAction:) forControlEvents:UIControlEventValueChanged]; return cell; diff --git a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/TextFieldViewController.m b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/TextFieldViewController.m index 9a2b396..7ab9588 100644 --- a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/TextFieldViewController.m +++ b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/TextFieldViewController.m @@ -7,6 +7,7 @@ #import "IQKeyboardReturnKeyHandler.h" #import "IQDropDownTextField.h" #import "IQUIView+IQKeyboardToolbar.h" +#import "IQKeyboardManagerConstantsInternal.h" @implementation TextFieldViewController { @@ -116,7 +117,10 @@ TextFieldViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:NSStringFromClass([TextFieldViewController class])]; UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:controller]; navigationController.navigationBar.tintColor = self.navigationController.navigationBar.tintColor; + +#if IQ_IS_XCODE_5_OR_GREATER navigationController.navigationBar.barTintColor = self.navigationController.navigationBar.barTintColor; +#endif navigationController.navigationBar.titleTextAttributes = self.navigationController.navigationBar.titleTextAttributes; [navigationController setModalTransitionStyle:arc4random()%4]; From 9b2e78afea7284fa973031e046f51627082a5d51 Mon Sep 17 00:00:00 2001 From: hackiftekhar Date: Tue, 7 Apr 2015 19:18:36 +0530 Subject: [PATCH 03/13] Added Xcode 4.2 compatibility --- .../Categories/IQUIView+Hierarchy.m | 5 +- .../IQKeyboardManagerConstantsInternal.h | 4 - IQKeyBoardManager/IQKeyboardManager.h | 6 +- IQKeyBoardManager/IQKeyboardManager.m | 51 ++++-- .../IQKeyboardReturnKeyHandler.h | 4 + .../IQKeyboardReturnKeyHandler.m | 41 +++-- .../IQSegmentedNextPrevious.h | 5 + .../IQSegmentedNextPrevious.m | 2 +- IQKeyBoardManager/IQTextView/IQTextView.m | 15 ++ .../IQToolbar/IQTitleBarButtonItem.h | 6 + .../IQToolbar/IQTitleBarButtonItem.m | 5 +- IQKeyBoardManager/IQToolbar/IQToolbar.m | 8 +- .../IQToolbar/IQUIView+IQKeyboardToolbar.m | 24 +-- .../UserInterfaceState.xcuserstate | Bin 115719 -> 139281 bytes .../CollectionViewDemoController.h | 4 + .../CollectionViewDemoController.m | 4 + .../IQDropDownTextField/IQDropDownTextField.h | 22 ++- .../IQDropDownTextField/IQDropDownTextField.m | 28 +++- .../ManualToolbarViewController.m | 6 + .../NavigationTableViewCell.m | 1 + .../OptionTableViewCell.m | 1 + .../OptionsViewController.m | 6 +- .../SettingsViewController.m | 147 +++++++++--------- .../SpecialCaseViewController.m | 2 + .../StepperTableViewCell.m | 2 + .../SwitchTableViewCell.m | 1 + .../TableViewInContainerViewController.m | 2 +- .../TextFieldViewController.m | 15 +- .../TextSelectionViewController.m | 9 +- .../TextViewSpecialCaseViewController.m | 6 + .../KeyboardTextFieldDemo/ViewController.m | 8 + README.md | 2 +- 32 files changed, 298 insertions(+), 144 deletions(-) diff --git a/IQKeyBoardManager/Categories/IQUIView+Hierarchy.m b/IQKeyBoardManager/Categories/IQUIView+Hierarchy.m index 48611c4..ef730ca 100644 --- a/IQKeyBoardManager/Categories/IQUIView+Hierarchy.m +++ b/IQKeyBoardManager/Categories/IQUIView+Hierarchy.m @@ -23,7 +23,10 @@ #import "IQUIView+Hierarchy.h" +#ifdef NSFoundationVersionNumber_iOS_5_1 #import +#endif + #import #import #import @@ -61,7 +64,7 @@ Class UISearchBarTextFieldClass; //UISearchBar -(void)_setIsAskingCanBecomeFirstResponder:(BOOL)isAskingCanBecomeFirstResponder { - objc_setAssociatedObject(self, @selector(isAskingCanBecomeFirstResponder), @(isAskingCanBecomeFirstResponder), OBJC_ASSOCIATION_ASSIGN); + objc_setAssociatedObject(self, @selector(isAskingCanBecomeFirstResponder), [NSNumber numberWithBool:isAskingCanBecomeFirstResponder], OBJC_ASSOCIATION_ASSIGN); } -(BOOL)isAskingCanBecomeFirstResponder diff --git a/IQKeyBoardManager/Constants/IQKeyboardManagerConstantsInternal.h b/IQKeyBoardManager/Constants/IQKeyboardManagerConstantsInternal.h index fbb15de..b3bb9aa 100644 --- a/IQKeyBoardManager/Constants/IQKeyboardManagerConstantsInternal.h +++ b/IQKeyBoardManager/Constants/IQKeyboardManagerConstantsInternal.h @@ -27,19 +27,15 @@ //Xcode 5 compatibility check #ifdef NSFoundationVersionNumber_iOS_6_1 #define IQ_IS_IOS7_OR_GREATER (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) - #define IQ_IS_XCODE_5_OR_GREATER 1 #else #define IQ_IS_IOS7_OR_GREATER NO - #define IQ_IS_XCODE_5_OR_GREATER 0 #endif //Xcode 6 compatibility check #ifdef NSFoundationVersionNumber_iOS_7_1 #define IQ_IS_IOS8_OR_GREATER (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1) - #define IQ_IS_XCODE_6_0_OR_GREATER 1 #else #define IQ_IS_IOS8_OR_GREATER NO - #define IQ_IS_XCODE_6_0_OR_GREATER 0 #endif #endif diff --git a/IQKeyBoardManager/IQKeyboardManager.h b/IQKeyBoardManager/IQKeyboardManager.h index 64d5cdf..59a6f1c 100755 --- a/IQKeyBoardManager/IQKeyboardManager.h +++ b/IQKeyBoardManager/IQKeyboardManager.h @@ -31,6 +31,10 @@ #import +#if !(__has_feature(objc_instancetype)) + #define instancetype id +#endif + @class UIFont; /** @const kIQDoneButtonToolbarTag Default tag for toolbar with Done button -1002. */ @@ -104,7 +108,7 @@ extern NSInteger const kIQPreviousNextButtonToolbarTag; */ @property(nonatomic, assign) IQAutoToolbarManageBehaviour toolbarManageBehaviour; -#if IQ_IS_XCODE_5_OR_GREATER +#ifdef NSFoundationVersionNumber_iOS_6_1 /** @property shouldToolbarUsesTextFieldTintColor diff --git a/IQKeyBoardManager/IQKeyboardManager.m b/IQKeyBoardManager/IQKeyboardManager.m index 85eb40e..0cbb365 100755 --- a/IQKeyBoardManager/IQKeyboardManager.m +++ b/IQKeyBoardManager/IQKeyboardManager.m @@ -36,9 +36,12 @@ #import #import #import -#import #import +#ifdef NSFoundationVersionNumber_iOS_5_1 +#import +#endif + NSInteger const kIQDoneButtonToolbarTag = -1002; NSInteger const kIQPreviousNextButtonToolbarTag = -1005; @@ -46,9 +49,6 @@ void _IQShowLog(NSString *logString); @interface IQKeyboardManager() -//Compatibility -@property(nonatomic, assign) BOOL shouldToolbarUsesTextFieldTintColor; - // Private helper methods - (void)adjustFrame; @@ -65,6 +65,9 @@ void _IQShowLog(NSString *logString); - (void)textFieldViewDidEndEditing:(NSNotification*)notification; - (void)textFieldViewDidChange:(NSNotification*)notification; +// Rotation notification +- (void)willChangeStatusBarOrientation:(NSNotification*)aNotification; + // Tap Recognizer - (void)tapRecognized:(UITapGestureRecognizer*)gesture; @@ -161,12 +164,17 @@ void _IQShowLog(NSString *logString); //IQToolbar handling @synthesize enableAutoToolbar = _enableAutoToolbar; @synthesize toolbarManageBehaviour = _toolbarManageBehaviour; + +#ifdef NSFoundationVersionNumber_iOS_6_1 @synthesize shouldToolbarUsesTextFieldTintColor = _shouldToolbarUsesTextFieldTintColor; +#endif + @synthesize shouldShowTextFieldPlaceholder = _shouldShowTextFieldPlaceholder; @synthesize placeholderFont = _placeholderFont; //TextView handling @synthesize canAdjustTextView = _canAdjustTextView; +@synthesize shouldFixTextViewClip = _shouldFixTextViewClip; //Resign handling @synthesize shouldResignOnTouchOutside = _shouldResignOnTouchOutside; @@ -177,6 +185,8 @@ void _IQShowLog(NSString *logString); //Animation handling @synthesize shouldAdoptDefaultKeyboardAnimation = _shouldAdoptDefaultKeyboardAnimation; +//ScrollView handling +@synthesize shouldRestoreScrollViewContentOffset= _shouldRestoreScrollViewContentOffset; #pragma mark - Initializing functions @@ -228,7 +238,6 @@ void _IQShowLog(NSString *logString); [self setShouldPlayInputClicks:NO]; [self setShouldResignOnTouchOutside:NO]; [self setOverrideKeyboardAppearance:NO]; - [self setShouldToolbarUsesTextFieldTintColor:NO]; [self setKeyboardAppearance:UIKeyboardAppearanceDefault]; [self setEnableAutoToolbar:YES]; @@ -242,7 +251,17 @@ void _IQShowLog(NSString *logString); //Initializing disabled classes Set. _disabledClasses = [[NSMutableSet alloc] initWithObjects:[UITableViewController class], nil]; _disabledToolbarClasses = [[NSMutableSet alloc] init]; + +#ifdef NSFoundationVersionNumber_iOS_6_1 + [self setShouldToolbarUsesTextFieldTintColor:NO]; +#endif + +#ifdef NSFoundationVersionNumber_iOS_5_1 _toolbarPreviousNextConsideredClass = [[NSMutableSet alloc] initWithObjects:[UITableView class],[UICollectionView class], nil]; +#else + _toolbarPreviousNextConsideredClass = [[NSMutableSet alloc] initWithObjects:[UITableView class], nil]; +#endif + }); } return self; @@ -798,7 +817,7 @@ void _IQShowLog(NSString *logString); if (_shouldAdoptDefaultKeyboardAnimation) { // Getting keyboard animation. - _animationCurve = [[aNotification userInfo][UIKeyboardAnimationCurveUserInfoKey] integerValue]; + _animationCurve = [[[aNotification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue]; _animationCurve = _animationCurve<<16; } else @@ -807,7 +826,7 @@ void _IQShowLog(NSString *logString); } // Getting keyboard animation duration - CGFloat duration = [[aNotification userInfo][UIKeyboardAnimationDurationUserInfoKey] floatValue]; + CGFloat duration = [[[aNotification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]; //Saving animation duration if (duration != 0.0) _animationDuration = duration; @@ -816,7 +835,7 @@ void _IQShowLog(NSString *logString); // Getting UIKeyboardSize. // CGRect screenRect = [self keyWindow].bounds; - CGRect kbFrame = [[aNotification userInfo][UIKeyboardFrameEndUserInfoKey] CGRectValue]; + CGRect kbFrame = [[[aNotification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; _kbSize = kbFrame.size; _IQShowLog([NSString stringWithFormat:@"UIKeyboard Size : %@",NSStringFromCGSize(_kbSize)]); @@ -901,7 +920,7 @@ void _IQShowLog(NSString *logString); _keyboardManagerFlags.isKeyboardShowing = NO; // Getting keyboard animation duration - CGFloat aDuration = [[aNotification userInfo][UIKeyboardAnimationDurationUserInfoKey] floatValue]; + CGFloat aDuration = [[[aNotification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue]; if (aDuration!= 0.0f) { // Setitng keyboard animation duration @@ -1284,7 +1303,7 @@ void _IQShowLog(NSString *logString); IQToolbar *toolbar = (IQToolbar*)[textField inputAccessoryView]; //Bar style according to keyboard appearance - if ([textField respondsToSelector:@selector(keyboardAppearance)]) + if (IQ_IS_IOS7_OR_GREATER && [textField respondsToSelector:@selector(keyboardAppearance)]) { switch ([(UITextField*)textField keyboardAppearance]) { @@ -1299,7 +1318,7 @@ void _IQShowLog(NSString *logString); { toolbar.barStyle = UIBarStyleDefault; -#if IQ_IS_XCODE_5_OR_GREATER +#ifdef NSFoundationVersionNumber_iOS_6_1 //Setting toolbar tintColor // (Enhancement ID: #30) if (_shouldToolbarUsesTextFieldTintColor && [toolbar respondsToSelector:@selector(tintColor)]) [toolbar setTintColor:[textField tintColor]]; @@ -1341,7 +1360,7 @@ void _IQShowLog(NSString *logString); IQToolbar *toolbar = (IQToolbar*)[textField inputAccessoryView]; //Bar style according to keyboard appearance - if ([textField respondsToSelector:@selector(keyboardAppearance)]) + if (IQ_IS_IOS7_OR_GREATER && [textField respondsToSelector:@selector(keyboardAppearance)]) { switch ([(UITextField*)textField keyboardAppearance]) { @@ -1356,7 +1375,7 @@ void _IQShowLog(NSString *logString); { toolbar.barStyle = UIBarStyleDefault; -#if IQ_IS_XCODE_5_OR_GREATER +#ifdef NSFoundationVersionNumber_iOS_6_1 //Setting toolbar tintColor // (Enhancement ID: #30) if (_shouldToolbarUsesTextFieldTintColor && [toolbar respondsToSelector:@selector(tintColor)]) [toolbar setTintColor:[textField tintColor]]; @@ -1369,7 +1388,7 @@ void _IQShowLog(NSString *logString); //In case of UITableView (Special), the next/previous buttons has to be refreshed everytime. (Bug ID: #56) // If firstTextField, then previous should not be enabled. - if (siblings[0] == textField) + if ([siblings objectAtIndex:0] == textField) { [textField setEnablePrevious:NO next:YES]; } @@ -1427,7 +1446,7 @@ void _IQShowLog(NSString *logString); //If it is not first textField. then it's previous object becomeFirstResponder. if (index > 0) { - UITextField *nextTextField = textFields[index-1]; + UITextField *nextTextField = [textFields objectAtIndex:index-1]; // Retaining textFieldView UIView *textFieldRetain = _textFieldView; @@ -1471,7 +1490,7 @@ void _IQShowLog(NSString *logString); //If it is not last textField. then it's next object becomeFirstResponder. if (index < textFields.count-1) { - UITextField *nextTextField = textFields[index+1]; + UITextField *nextTextField = [textFields objectAtIndex:index+1]; // Retaining textFieldView UIView *textFieldRetain = _textFieldView; diff --git a/IQKeyBoardManager/IQKeyboardReturnKeyHandler.h b/IQKeyBoardManager/IQKeyboardReturnKeyHandler.h index ae7637a..fa54f8a 100644 --- a/IQKeyBoardManager/IQKeyboardReturnKeyHandler.h +++ b/IQKeyBoardManager/IQKeyboardReturnKeyHandler.h @@ -29,6 +29,10 @@ #import #import +#if !(__has_feature(objc_instancetype)) + #define instancetype id +#endif + @class UITextField,UIView, UIViewController; /** diff --git a/IQKeyBoardManager/IQKeyboardReturnKeyHandler.m b/IQKeyBoardManager/IQKeyboardReturnKeyHandler.m index e4698ed..de24f4d 100644 --- a/IQKeyBoardManager/IQKeyboardReturnKeyHandler.m +++ b/IQKeyBoardManager/IQKeyboardReturnKeyHandler.m @@ -23,7 +23,6 @@ #import "IQKeyboardReturnKeyHandler.h" -#import "IQKeyboardManagerConstantsInternal.h" #import "IQUIView+Hierarchy.h" #import "IQNSArray+Sort.h" @@ -33,7 +32,10 @@ #import #import #import + +#ifdef NSFoundationVersionNumber_iOS_5_1 #import +#endif NSString *const kIQTextField = @"kIQTextField"; NSString *const kIQTextFieldDelegate = @"kIQTextFieldDelegate"; @@ -42,6 +44,8 @@ NSString *const kIQTextFieldReturnKeyType = @"kIQTextFieldReturnKeyType"; @interface IQKeyboardReturnKeyHandler () +-(void)updateReturnKeyTypeOnTextField:(UIView*)textField; + @end @implementation IQKeyboardReturnKeyHandler @@ -49,6 +53,10 @@ NSString *const kIQTextFieldReturnKeyType = @"kIQTextFieldReturnKeyType"; NSMutableSet *textFieldInfoCache; } +@synthesize lastTextFieldReturnKeyType = _lastTextFieldReturnKeyType; +@synthesize toolbarManageBehaviour = _toolbarManageBehaviour; +@synthesize delegate = _delegate; + -(instancetype)initWithViewController:(UIViewController*)controller { self = [super init]; @@ -65,7 +73,7 @@ NSString *const kIQTextFieldReturnKeyType = @"kIQTextFieldReturnKeyType"; -(NSDictionary*)textFieldCachedInfo:(UITextField*)textField { for (NSDictionary *infoDict in textFieldInfoCache) - if (infoDict[kIQTextField] == textField) return infoDict; + if ([infoDict objectForKey:kIQTextField] == textField) return infoDict; return nil; } @@ -91,8 +99,8 @@ NSString *const kIQTextFieldReturnKeyType = @"kIQTextFieldReturnKeyType"; if (dict) { - textField.keyboardType = [dict[kIQTextFieldReturnKeyType] integerValue]; - textField.delegate = dict[kIQTextFieldDelegate]; + textField.keyboardType = [[dict objectForKey:kIQTextFieldReturnKeyType] integerValue]; + textField.delegate = [dict objectForKey:kIQTextFieldDelegate]; [textFieldInfoCache removeObject:dict]; } } @@ -101,10 +109,11 @@ NSString *const kIQTextFieldReturnKeyType = @"kIQTextFieldReturnKeyType"; { NSMutableDictionary *dictInfo = [[NSMutableDictionary alloc] init]; - dictInfo[kIQTextField] = textField; - dictInfo[kIQTextFieldReturnKeyType] = @([textField returnKeyType]); + [dictInfo setObject:textField forKey:kIQTextField]; + [dictInfo setObject:[NSNumber numberWithInteger:textField.returnKeyType] forKey:kIQTextFieldReturnKeyType]; - if (textField.delegate) dictInfo[kIQTextFieldDelegate] = textField.delegate; + if (textField.delegate) [dictInfo setObject:textField.delegate forKey:kIQTextFieldDelegate]; + [textField setDelegate:self]; [textFieldInfoCache addObject:dictInfo]; @@ -117,7 +126,7 @@ NSString *const kIQTextFieldReturnKeyType = @"kIQTextFieldReturnKeyType"; for (NSDictionary *infoDict in textFieldInfoCache) { - UITextField *textField = infoDict[kIQTextField]; + UITextField *textField = [infoDict objectForKey:kIQTextField]; [self updateReturnKeyTypeOnTextField:textField]; } @@ -126,7 +135,11 @@ NSString *const kIQTextFieldReturnKeyType = @"kIQTextFieldReturnKeyType"; -(void)updateReturnKeyTypeOnTextField:(UIView*)textField { UIView *tableView = [textField superviewOfClassType:[UITableView class]]; + +#ifdef NSFoundationVersionNumber_iOS_5_1 if (tableView == nil) tableView = [textField superviewOfClassType:[UICollectionView class]]; +#endif + NSArray *textFields = nil; @@ -167,7 +180,9 @@ NSString *const kIQTextFieldReturnKeyType = @"kIQTextFieldReturnKeyType"; -(void)goToNextResponderOrResign:(UIView*)textField { UIView *tableView = [textField superviewOfClassType:[UITableView class]]; +#ifdef NSFoundationVersionNumber_iOS_5_1 if (tableView == nil) tableView = [textField superviewOfClassType:[UICollectionView class]]; +#endif NSArray *textFields = nil; @@ -205,7 +220,7 @@ NSString *const kIQTextFieldReturnKeyType = @"kIQTextFieldReturnKeyType"; NSUInteger index = [textFields indexOfObject:textField]; //If it is not last textField. then it's next object becomeFirstResponder. - (index < textFields.count-1) ? [textFields[index+1] becomeFirstResponder] : [textField resignFirstResponder]; + (index < textFields.count-1) ? [[textFields objectAtIndex:index+1] becomeFirstResponder] : [textField resignFirstResponder]; } } @@ -330,7 +345,7 @@ NSString *const kIQTextFieldReturnKeyType = @"kIQTextFieldReturnKeyType"; [self.delegate textViewDidChangeSelection:textView]; } -#if IQ_IS_XCODE_5_OR_GREATER +#ifdef NSFoundationVersionNumber_iOS_6_1 - (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange { @@ -354,9 +369,9 @@ NSString *const kIQTextFieldReturnKeyType = @"kIQTextFieldReturnKeyType"; { for (NSDictionary *dict in textFieldInfoCache) { - UITextField *textField = dict[kIQTextField]; - textField.keyboardType = [dict[kIQTextFieldReturnKeyType] integerValue]; - textField.delegate = dict[kIQTextFieldDelegate]; + UITextField *textField = [dict objectForKey:kIQTextField]; + textField.keyboardType = [[dict objectForKey:kIQTextFieldReturnKeyType] integerValue]; + textField.delegate = [dict objectForKey:kIQTextFieldDelegate]; } [textFieldInfoCache removeAllObjects]; diff --git a/IQKeyBoardManager/IQSegmentedNextPrevious/IQSegmentedNextPrevious.h b/IQKeyBoardManager/IQSegmentedNextPrevious/IQSegmentedNextPrevious.h index b5d2bfe..94d0d88 100644 --- a/IQKeyBoardManager/IQSegmentedNextPrevious/IQSegmentedNextPrevious.h +++ b/IQKeyBoardManager/IQSegmentedNextPrevious/IQSegmentedNextPrevious.h @@ -27,6 +27,11 @@ #import +#if !(__has_feature(objc_instancetype)) + #define instancetype id +#endif + + /** @class IQSegmentedNextPrevious diff --git a/IQKeyBoardManager/IQSegmentedNextPrevious/IQSegmentedNextPrevious.m b/IQKeyBoardManager/IQSegmentedNextPrevious/IQSegmentedNextPrevious.m index a9298ef..b083b1f 100644 --- a/IQKeyBoardManager/IQSegmentedNextPrevious/IQSegmentedNextPrevious.m +++ b/IQKeyBoardManager/IQSegmentedNextPrevious/IQSegmentedNextPrevious.m @@ -44,7 +44,7 @@ -(instancetype)initWithTarget:(id)target previousAction:(SEL)previousAction nextAction:(SEL)nextAction { // Creating it with two items, Previous/Next. - self = [super initWithItems:@[IQLocalizedString(@"Previous", nil),IQLocalizedString(@"Next", nil)]]; + self = [super initWithItems:[NSArray arrayWithObjects:IQLocalizedString(@"Previous", nil),IQLocalizedString(@"Next", nil), nil]]; if (self) { diff --git a/IQKeyBoardManager/IQTextView/IQTextView.m b/IQKeyBoardManager/IQTextView/IQTextView.m index 6fef727..ea05422 100644 --- a/IQKeyBoardManager/IQTextView/IQTextView.m +++ b/IQKeyBoardManager/IQTextView/IQTextView.m @@ -26,6 +26,21 @@ #import #import +#if !(__has_feature(objc_instancetype)) + #define instancetype id +#endif + +//Xcode 4.5 compatibility check +#ifndef NSFoundationVersionNumber_iOS_5_1 + #define NSLineBreakByWordWrapping UILineBreakModeWordWrap +#endif + +@interface IQTextView () + +-(void)refreshPlaceholder; + +@end + @implementation IQTextView { UILabel *placeHolderLabel; diff --git a/IQKeyBoardManager/IQToolbar/IQTitleBarButtonItem.h b/IQKeyBoardManager/IQToolbar/IQTitleBarButtonItem.h index 1282a87..5468509 100644 --- a/IQKeyBoardManager/IQToolbar/IQTitleBarButtonItem.h +++ b/IQKeyBoardManager/IQToolbar/IQTitleBarButtonItem.h @@ -24,6 +24,12 @@ #import #import "IQKeyboardManagerConstants.h" #import "IQBarButtonItem.h" + +#if !(__has_feature(objc_instancetype)) + #define instancetype id +#endif + + /** @author Iftekhar Qurashi diff --git a/IQKeyBoardManager/IQToolbar/IQTitleBarButtonItem.m b/IQKeyBoardManager/IQToolbar/IQTitleBarButtonItem.m index 47046eb..f116a04 100644 --- a/IQKeyBoardManager/IQToolbar/IQTitleBarButtonItem.m +++ b/IQKeyBoardManager/IQToolbar/IQTitleBarButtonItem.m @@ -23,9 +23,12 @@ #import "IQTitleBarButtonItem.h" #import "IQKeyboardManagerConstants.h" - #import +#ifndef NSFoundationVersionNumber_iOS_5_1 + #define NSTextAlignmentCenter UITextAlignmentCenter +#endif + @implementation IQTitleBarButtonItem { UILabel *_titleLabel; diff --git a/IQKeyBoardManager/IQToolbar/IQToolbar.m b/IQKeyBoardManager/IQToolbar/IQToolbar.m index c5d8519..2c0d1eb 100644 --- a/IQKeyBoardManager/IQToolbar/IQToolbar.m +++ b/IQKeyBoardManager/IQToolbar/IQToolbar.m @@ -28,8 +28,14 @@ #import +#if !(__has_feature(objc_instancetype)) + #define instancetype id +#endif + + @implementation IQToolbar @synthesize titleFont = _titleFont; +@synthesize title = _title; +(void)initialize { @@ -37,7 +43,7 @@ [[self appearance] setTintColor:nil]; -#if IQ_IS_XCODE_5_OR_GREATER +#ifdef NSFoundationVersionNumber_iOS_6_1 if ([[self appearance] respondsToSelector:@selector(setBarTintColor:)]) { [[self appearance] setBarTintColor:nil]; diff --git a/IQKeyBoardManager/IQToolbar/IQUIView+IQKeyboardToolbar.m b/IQKeyBoardManager/IQToolbar/IQUIView+IQKeyboardToolbar.m index 2ec058c..582a521 100644 --- a/IQKeyBoardManager/IQToolbar/IQUIView+IQKeyboardToolbar.m +++ b/IQKeyBoardManager/IQToolbar/IQUIView+IQKeyboardToolbar.m @@ -38,7 +38,7 @@ -(void)setShouldHideTitle:(BOOL)shouldHideTitle { - objc_setAssociatedObject(self, @selector(shouldHideTitle), @(shouldHideTitle), OBJC_ASSOCIATION_ASSIGN); + objc_setAssociatedObject(self, @selector(shouldHideTitle), [NSNumber numberWithBool:shouldHideTitle], OBJC_ASSOCIATION_ASSIGN); } -(BOOL)shouldHideTitle @@ -115,7 +115,7 @@ // Creating a toolBar for keyboard IQToolbar *toolbar = [[IQToolbar alloc] init]; - if ([self respondsToSelector:@selector(keyboardAppearance)]) + if (IQ_IS_IOS7_OR_GREATER && [self respondsToSelector:@selector(keyboardAppearance)]) { switch ([(UITextField*)self keyboardAppearance]) { @@ -188,7 +188,7 @@ // Creating a toolBar for keyboard IQToolbar *toolbar = [[IQToolbar alloc] init]; - if ([self respondsToSelector:@selector(keyboardAppearance)]) + if (IQ_IS_IOS7_OR_GREATER && [self respondsToSelector:@selector(keyboardAppearance)]) { switch ([(UITextField*)self keyboardAppearance]) { @@ -262,7 +262,7 @@ // Creating a toolBar for keyboard IQToolbar *toolbar = [[IQToolbar alloc] init]; - if ([self respondsToSelector:@selector(keyboardAppearance)]) + if (IQ_IS_IOS7_OR_GREATER && [self respondsToSelector:@selector(keyboardAppearance)]) { switch ([(UITextField*)self keyboardAppearance]) { @@ -340,7 +340,7 @@ // Creating a toolBar for keyboard IQToolbar *toolbar = [[IQToolbar alloc] init]; - if ([self respondsToSelector:@selector(keyboardAppearance)]) + if (IQ_IS_IOS7_OR_GREATER && [self respondsToSelector:@selector(keyboardAppearance)]) { switch ([(UITextField*)self keyboardAppearance]) { @@ -418,7 +418,7 @@ // Creating a toolBar for phoneNumber keyboard IQToolbar *toolbar = [[IQToolbar alloc] init]; - if ([self respondsToSelector:@selector(keyboardAppearance)]) + if (IQ_IS_IOS7_OR_GREATER && [self respondsToSelector:@selector(keyboardAppearance)]) { switch ([(UITextField*)self keyboardAppearance]) { @@ -441,7 +441,7 @@ UIImage *imageRightArrow; //Xcode Compilation check -#if IQ_IS_XCODE_6_0_OR_GREATER +#ifdef NSFoundationVersionNumber_iOS_7_1 if (IQ_IS_IOS8_OR_GREATER) { @@ -544,7 +544,7 @@ // Creating a toolBar for phoneNumber keyboard IQToolbar *toolbar = [[IQToolbar alloc] init]; - if ([self respondsToSelector:@selector(keyboardAppearance)]) + if (IQ_IS_IOS7_OR_GREATER && [self respondsToSelector:@selector(keyboardAppearance)]) { switch ([(UITextField*)self keyboardAppearance]) { @@ -567,7 +567,7 @@ UIImage *imageRightArrow; //Xcode Compilation check -#if IQ_IS_XCODE_6_0_OR_GREATER +#ifdef NSFoundationVersionNumber_iOS_7_1 if (IQ_IS_IOS8_OR_GREATER) { @@ -674,8 +674,8 @@ if (IQ_IS_IOS7_OR_GREATER && [[inputAccessoryView items] count]>3) { // Getting first item from inputAccessoryView. - IQBarButtonItem *prevButton = (IQBarButtonItem*)[inputAccessoryView items][0]; - IQBarButtonItem *nextButton = (IQBarButtonItem*)[inputAccessoryView items][2]; + IQBarButtonItem *prevButton = (IQBarButtonItem*)[[inputAccessoryView items] objectAtIndex:0]; + IQBarButtonItem *nextButton = (IQBarButtonItem*)[[inputAccessoryView items] objectAtIndex:2]; // If it is UIBarButtonItem and it's customView is not nil. if ([prevButton isKindOfClass:[IQBarButtonItem class]] && [nextButton isKindOfClass:[IQBarButtonItem class]]) @@ -689,7 +689,7 @@ else { // Getting first item from inputAccessoryView. - IQBarButtonItem *barButtonItem = (IQBarButtonItem*)[inputAccessoryView items][0]; + IQBarButtonItem *barButtonItem = (IQBarButtonItem*)[[inputAccessoryView items] objectAtIndex:0]; // If it is IQBarButtonItem and it's customView is not nil. if ([barButtonItem isKindOfClass:[IQBarButtonItem class]] && [barButtonItem customView] != nil) diff --git a/KeyboardTextFieldDemo/IQKeyboardManager.xcodeproj/project.xcworkspace/xcuserdata/iftekhar.xcuserdatad/UserInterfaceState.xcuserstate b/KeyboardTextFieldDemo/IQKeyboardManager.xcodeproj/project.xcworkspace/xcuserdata/iftekhar.xcuserdatad/UserInterfaceState.xcuserstate index e40b59d61d238aad3fdf051f8f51ece8aad9c427..08baf48301004da84a7fa1ae89d13c41bd06af8b 100644 GIT binary patch literal 139281 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 SUyCpQfB*Xb|2f)v=>Gtb4&^EU literal 115719 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�0L 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 YzyDla=KuY-{_FqmzyJT=q14U)2XNcwXaE2J diff --git a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/CollectionViewDemoController.h b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/CollectionViewDemoController.h index a23215f..f4ed85c 100644 --- a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/CollectionViewDemoController.h +++ b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/CollectionViewDemoController.h @@ -8,6 +8,10 @@ #import +#ifdef NSFoundationVersionNumber_iOS_5_1 + @interface CollectionViewDemoController : UIViewController @end + +#endif \ No newline at end of file diff --git a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/CollectionViewDemoController.m b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/CollectionViewDemoController.m index 206f951..53b7acd 100644 --- a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/CollectionViewDemoController.m +++ b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/CollectionViewDemoController.m @@ -8,6 +8,8 @@ #import "CollectionViewDemoController.h" +#ifdef NSFoundationVersionNumber_iOS_5_1 + @interface CollectionViewDemoController () @end @@ -36,3 +38,5 @@ } @end + +#endif \ No newline at end of file diff --git a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/IQDropDownTextField/IQDropDownTextField.h b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/IQDropDownTextField/IQDropDownTextField.h index 40ebc43..a6fe781 100755 --- a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/IQDropDownTextField/IQDropDownTextField.h +++ b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/IQDropDownTextField/IQDropDownTextField.h @@ -24,6 +24,10 @@ #import +#if !(__has_feature(objc_instancetype)) + #define instancetype id +#endif + /** @enum IQDropDownMode @@ -36,15 +40,25 @@ @const IQDropDownModeDatePicker Show UIDatePicker to pick date. */ -typedef NS_ENUM(NSInteger, IQDropDownMode) { - +#ifndef NS_ENUM + +typedef enum IQDropDownMode { + IQDropDownModeTextPicker, + IQDropDownModeTimePicker, + IQDropDownModeDatePicker, +}IQDropDownMode; + +#else + +typedef NS_ENUM(NSInteger, IQDropDownMode) { IQDropDownModeTextPicker, - IQDropDownModeTimePicker, - IQDropDownModeDatePicker, }; +#endif + + @class IQDropDownTextField; /** diff --git a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/IQDropDownTextField/IQDropDownTextField.m b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/IQDropDownTextField/IQDropDownTextField.m index 18fe57a..6f8b57f 100755 --- a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/IQDropDownTextField/IQDropDownTextField.m +++ b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/IQDropDownTextField/IQDropDownTextField.m @@ -24,6 +24,11 @@ #import "IQDropDownTextField.h" +#ifndef NSFoundationVersionNumber_iOS_5_1 + #define NSTextAlignmentCenter UITextAlignmentCenter +#endif + + @interface IQDropDownTextField () { NSArray *_ItemListsInternal; @@ -35,10 +40,25 @@ @property (nonatomic, strong) NSDateFormatter *dropDownDateFormatter; @property (nonatomic, strong) NSDateFormatter *dropDownTimeFormatter; +- (void)dateChanged:(UIDatePicker *)dPicker; +- (void)timeChanged:(UIDatePicker *)tPicker; + @end @implementation IQDropDownTextField +@synthesize dropDownMode = _dropDownMode; +@synthesize itemList = _itemList; +@synthesize selectedItem = _selectedItem; +@synthesize isOptionalDropDown = _isOptionalDropDown; +@synthesize datePickerMode = _datePickerMode; +@synthesize minimumDate = _minimumDate; +@synthesize maximumDate = _maximumDate; +@synthesize delegate; + +@synthesize pickerView,datePicker, timePicker, dropDownDateFormatter,dropDownTimeFormatter; +@synthesize dateFormatter, timeFormatter; + #pragma mark - Initialization - (void)initialize @@ -129,7 +149,7 @@ UILabel *labelText = [[UILabel alloc] init]; [labelText setTextAlignment:NSTextAlignmentCenter]; [labelText setAdjustsFontSizeToFitWidth:YES]; - [labelText setText:_ItemListsInternal[row]]; + [labelText setText:[_ItemListsInternal objectAtIndex:row]]; labelText.backgroundColor = [UIColor clearColor]; if (self.isOptionalDropDown && row == 0) @@ -147,7 +167,7 @@ - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { - [self setSelectedItem:_ItemListsInternal[row]]; + [self setSelectedItem:[_ItemListsInternal objectAtIndex:row]]; } #pragma mark - UIDatePicker delegate @@ -191,7 +211,7 @@ } else { - self.text = _ItemListsInternal[row]; + self.text = [_ItemListsInternal objectAtIndex:row]; } [self.pickerView selectRow:row inComponent:0 animated:animated]; @@ -384,7 +404,7 @@ if (_isOptionalDropDown) { - NSArray *array = @[@"Select"]; + NSArray *array = [NSArray arrayWithObject:@"Select"]; _ItemListsInternal = [array arrayByAddingObjectsFromArray:_itemList]; } else diff --git a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/ManualToolbarViewController.m b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/ManualToolbarViewController.m index c8de529..e61e81e 100644 --- a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/ManualToolbarViewController.m +++ b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/ManualToolbarViewController.m @@ -12,6 +12,12 @@ @interface ManualToolbarViewController () +-(void)previousAction:(id)sender; +-(void)nextAction:(id)sender; +-(void)doneAction:(id)sender; + + + @end @implementation ManualToolbarViewController diff --git a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/NavigationTableViewCell.m b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/NavigationTableViewCell.m index dbb0bda..c0e6333 100644 --- a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/NavigationTableViewCell.m +++ b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/NavigationTableViewCell.m @@ -9,6 +9,7 @@ #import "NavigationTableViewCell.h" @implementation NavigationTableViewCell +@synthesize labelTitle, labelSubtitle; - (void)awakeFromNib { diff --git a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/OptionTableViewCell.m b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/OptionTableViewCell.m index 1f05203..dd6cb91 100644 --- a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/OptionTableViewCell.m +++ b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/OptionTableViewCell.m @@ -9,6 +9,7 @@ #import "OptionTableViewCell.h" @implementation OptionTableViewCell +@synthesize labelOption; - (void)awakeFromNib { diff --git a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/OptionsViewController.m b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/OptionsViewController.m index 4001533..c2a8d31 100644 --- a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/OptionsViewController.m +++ b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/OptionsViewController.m @@ -15,6 +15,8 @@ @implementation OptionsViewController +@synthesize delegate, options, selectedIndex; + - (void)viewDidLoad { [super viewDidLoad]; @@ -27,9 +29,9 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - OptionTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([OptionTableViewCell class]) forIndexPath:indexPath]; + OptionTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([OptionTableViewCell class])]; - cell.labelOption.text = self.options[indexPath.row]; + cell.labelOption.text = [self.options objectAtIndex:indexPath.row]; cell.accessoryType = (indexPath.row == self.selectedIndex) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; diff --git a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/SettingsViewController.m b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/SettingsViewController.m index a673f1e..002c357 100644 --- a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/SettingsViewController.m +++ b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/SettingsViewController.m @@ -33,32 +33,33 @@ { [super viewDidLoad]; - sectionTitles = @[@"UIKeyboard Handling", + sectionTitles = [NSArray arrayWithObjects:@"UIKeyboard Handling", @"IQToolbar handling", @"UITextView handling", @"Keyboard appearance overriding", @"Resign first responder handling", @"Sound handling", - @"Animation handling"]; + @"Animation handling",nil]; - keyboardManagerProperties = @[@[@"Enable", @"Keyboard Distance From TextField", @"Prevent Showing Bottom Blank Space"], - @[@"Enable Auto Toolbar",@"Toolbar Manage Behaviour",@"Should Toolbar Uses TextField TintColor",@"Should Show TextField Placeholder",@"Placeholder Font"], - @[@"Can Adjust TextView"], - @[@"Override Keyboard Appearance",@"Keyboard Appearance"], - @[@"Should Resign On Touch Outside"], - @[@"Should Play Input Clicks"], - @[@"Should Adopt Default Keyboard Animation"], - ]; + keyboardManagerProperties = [NSArray arrayWithObjects: + [NSArray arrayWithObjects:@"Enable", @"Keyboard Distance From TextField", @"Prevent Showing Bottom Blank Space",nil], + [NSArray arrayWithObjects:@"Enable Auto Toolbar",@"Toolbar Manage Behaviour",@"Should Toolbar Uses TextField TintColor",@"Should Show TextField Placeholder",@"Placeholder Font",nil], + [NSArray arrayWithObjects:@"Can Adjust TextView",nil], + [NSArray arrayWithObjects:@"Override Keyboard Appearance",@"Keyboard Appearance",nil], + [NSArray arrayWithObjects:@"Should Resign On Touch Outside",nil], + [NSArray arrayWithObjects:@"Should Play Input Clicks",nil], + [NSArray arrayWithObjects:@"Should Adopt Default Keyboard Animation",nil],nil]; - keyboardManagerPropertyDetails = @[@[@"Enable/Disable IQKeyboardManager",@"Set keyboard distance from textField",@"Prevent to show blank space between UIKeyboard and View"], - @[@"Automatic add the IQToolbar on UIKeyboard",@"AutoToolbar previous/next button managing behaviour",@"Uses textField's tintColor property for IQToolbar",@"Add the textField's placeholder text on IQToolbar",@"UIFont for IQToolbar placeholder text"], - @[@"Adjust textView's frame when it is too big in height"], - @[@"Override the keyboardAppearance for all UITextField/UITextView",@"All the UITextField keyboardAppearance is set using this property"], - @[@"Resigns Keyboard on touching outside of UITextField/View"], - @[@"plays inputClick sound on next/previous/done click"], - @[@"uses keyboard default animation curve style to move view"]]; + keyboardManagerPropertyDetails = [NSArray arrayWithObjects: + [NSArray arrayWithObjects:@"Enable/Disable IQKeyboardManager",@"Set keyboard distance from textField",@"Prevent to show blank space between UIKeyboard and View",nil], + [NSArray arrayWithObjects:@"Automatic add the IQToolbar on UIKeyboard",@"AutoToolbar previous/next button managing behaviour",@"Uses textField's tintColor property for IQToolbar",@"Add the textField's placeholder text on IQToolbar",@"UIFont for IQToolbar placeholder text",nil], + [NSArray arrayWithObjects:@"Adjust textView's frame when it is too big in height",nil], + [NSArray arrayWithObjects:@"Override the keyboardAppearance for all UITextField/UITextView",@"All the UITextField keyboardAppearance is set using this property",nil], + [NSArray arrayWithObjects:@"Resigns Keyboard on touching outside of UITextField/View",nil], + [NSArray arrayWithObjects:@"plays inputClick sound on next/previous/done click",nil], + [NSArray arrayWithObjects:@"uses keyboard default animation curve style to move view",nil],nil]; } - (IBAction)doneAction:(UIBarButtonItem *)sender @@ -78,7 +79,7 @@ - (void)keyboardDistanceFromTextFieldAction:(UIStepper *)sender { [[IQKeyboardManager sharedManager] setKeyboardDistanceFromTextField:sender.value]; - [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:1 inSection:0]] withRowAnimation:UITableViewRowAnimationNone]; + [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:1 inSection:0]] withRowAnimation:UITableViewRowAnimationNone]; } - (void)preventShowingBottomBlankSpaceAction:(UISwitch *)sender @@ -99,7 +100,7 @@ - (void)shouldToolbarUsesTextFieldTintColorAction:(UISwitch *)sender { -#if IQ_IS_XCODE_5_OR_GREATER +#ifdef NSFoundationVersionNumber_iOS_6_1 [[IQKeyboardManager sharedManager] setShouldToolbarUsesTextFieldTintColor:sender.on]; #endif } @@ -162,7 +163,7 @@ { case 0: { - return ([[IQKeyboardManager sharedManager] isEnabled] == NO) ? 1: [keyboardManagerProperties[section] count]; + return ([[IQKeyboardManager sharedManager] isEnabled] == NO) ? 1: [[keyboardManagerProperties objectAtIndex:section] count]; } break; case 1: @@ -177,20 +178,20 @@ } else { - return [keyboardManagerProperties[section] count]; + return [[keyboardManagerProperties objectAtIndex:section] count]; } } break; case 3: { - return ([[IQKeyboardManager sharedManager] overrideKeyboardAppearance] == NO) ? 1: [keyboardManagerProperties[section] count]; + return ([[IQKeyboardManager sharedManager] overrideKeyboardAppearance] == NO) ? 1: [[keyboardManagerProperties objectAtIndex:section] count]; } break; case 2: case 4: case 5: case 6: - return [keyboardManagerProperties[section] count]; + return [[keyboardManagerProperties objectAtIndex:section] count]; break; default: @@ -201,7 +202,7 @@ -(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { - return sectionTitles[section]; + return [sectionTitles objectAtIndex:section]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath @@ -214,9 +215,9 @@ { case 0: { - SwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SwitchTableViewCell class]) forIndexPath:indexPath]; - cell.labelTitle.text = keyboardManagerProperties[indexPath.section][indexPath.row]; - cell.labelSubtitle.text = keyboardManagerPropertyDetails[indexPath.section][indexPath.row]; + SwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SwitchTableViewCell class])]; + cell.labelTitle.text = [[keyboardManagerProperties objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; + cell.labelSubtitle.text = [[keyboardManagerPropertyDetails objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; cell.switchEnable.on = [[IQKeyboardManager sharedManager] isEnabled]; [cell.switchEnable removeTarget:nil action:NULL forControlEvents:UIControlEventAllEvents]; [cell.switchEnable addTarget:self action:@selector(enableAction:) forControlEvents:UIControlEventValueChanged]; @@ -225,9 +226,9 @@ break; case 1: { - StepperTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([StepperTableViewCell class]) forIndexPath:indexPath]; - cell.labelTitle.text = keyboardManagerProperties[indexPath.section][indexPath.row]; - cell.labelSubtitle.text = keyboardManagerPropertyDetails[indexPath.section][indexPath.row]; + StepperTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([StepperTableViewCell class])]; + cell.labelTitle.text = [[keyboardManagerProperties objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; + cell.labelSubtitle.text = [[keyboardManagerPropertyDetails objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; cell.stepper.value = [[IQKeyboardManager sharedManager] keyboardDistanceFromTextField]; cell.labelStepperValue.text = [NSString stringWithFormat:@"%.0f",[[IQKeyboardManager sharedManager] keyboardDistanceFromTextField]]; [cell.stepper removeTarget:nil action:NULL forControlEvents:UIControlEventAllEvents]; @@ -237,9 +238,9 @@ break; case 2: { - SwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SwitchTableViewCell class]) forIndexPath:indexPath]; - cell.labelTitle.text = keyboardManagerProperties[indexPath.section][indexPath.row]; - cell.labelSubtitle.text = keyboardManagerPropertyDetails[indexPath.section][indexPath.row]; + SwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SwitchTableViewCell class])]; + cell.labelTitle.text = [[keyboardManagerProperties objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; + cell.labelSubtitle.text = [[keyboardManagerPropertyDetails objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; cell.switchEnable.on = [[IQKeyboardManager sharedManager] preventShowingBottomBlankSpace]; [cell.switchEnable removeTarget:nil action:NULL forControlEvents:UIControlEventAllEvents]; [cell.switchEnable addTarget:self action:@selector(preventShowingBottomBlankSpaceAction:) forControlEvents:UIControlEventValueChanged]; @@ -255,9 +256,9 @@ { case 0: { - SwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SwitchTableViewCell class]) forIndexPath:indexPath]; - cell.labelTitle.text = keyboardManagerProperties[indexPath.section][indexPath.row]; - cell.labelSubtitle.text = keyboardManagerPropertyDetails[indexPath.section][indexPath.row]; + SwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SwitchTableViewCell class])]; + cell.labelTitle.text = [[keyboardManagerProperties objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; + cell.labelSubtitle.text = [[keyboardManagerPropertyDetails objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; cell.switchEnable.on = [[IQKeyboardManager sharedManager] isEnableAutoToolbar]; [cell.switchEnable removeTarget:nil action:NULL forControlEvents:UIControlEventAllEvents]; [cell.switchEnable addTarget:self action:@selector(enableAutoToolbarAction:) forControlEvents:UIControlEventValueChanged]; @@ -266,19 +267,19 @@ break; case 1: { - NavigationTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([NavigationTableViewCell class]) forIndexPath:indexPath]; - cell.labelTitle.text = keyboardManagerProperties[indexPath.section][indexPath.row]; - cell.labelSubtitle.text = keyboardManagerPropertyDetails[indexPath.section][indexPath.row]; + NavigationTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([NavigationTableViewCell class])]; + cell.labelTitle.text = [[keyboardManagerProperties objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; + cell.labelSubtitle.text = [[keyboardManagerPropertyDetails objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; return cell; } break; case 2: { - SwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SwitchTableViewCell class]) forIndexPath:indexPath]; - cell.labelTitle.text = keyboardManagerProperties[indexPath.section][indexPath.row]; - cell.labelSubtitle.text = keyboardManagerPropertyDetails[indexPath.section][indexPath.row]; + SwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SwitchTableViewCell class])]; + cell.labelTitle.text = [[keyboardManagerProperties objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; + cell.labelSubtitle.text = [[keyboardManagerPropertyDetails objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; -#if IQ_IS_XCODE_5_OR_GREATER +#ifdef NSFoundationVersionNumber_iOS_6_1 cell.switchEnable.on = [[IQKeyboardManager sharedManager] shouldToolbarUsesTextFieldTintColor]; #else cell.switchEnable.on = NO; @@ -291,9 +292,9 @@ break; case 3: { - SwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SwitchTableViewCell class]) forIndexPath:indexPath]; - cell.labelTitle.text = keyboardManagerProperties[indexPath.section][indexPath.row]; - cell.labelSubtitle.text = keyboardManagerPropertyDetails[indexPath.section][indexPath.row]; + SwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SwitchTableViewCell class])]; + cell.labelTitle.text = [[keyboardManagerProperties objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; + cell.labelSubtitle.text = [[keyboardManagerPropertyDetails objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; cell.switchEnable.on = [[IQKeyboardManager sharedManager] shouldShowTextFieldPlaceholder]; [cell.switchEnable removeTarget:nil action:NULL forControlEvents:UIControlEventAllEvents]; [cell.switchEnable addTarget:self action:@selector(shouldShowTextFieldPlaceholder:) forControlEvents:UIControlEventValueChanged]; @@ -302,9 +303,9 @@ break; case 4: { - NavigationTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([NavigationTableViewCell class]) forIndexPath:indexPath]; - cell.labelTitle.text = keyboardManagerProperties[indexPath.section][indexPath.row]; - cell.labelSubtitle.text = keyboardManagerPropertyDetails[indexPath.section][indexPath.row]; + NavigationTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([NavigationTableViewCell class])]; + cell.labelTitle.text = [[keyboardManagerProperties objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; + cell.labelSubtitle.text = [[keyboardManagerPropertyDetails objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; return cell; } break; @@ -317,9 +318,9 @@ { case 0: { - SwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SwitchTableViewCell class]) forIndexPath:indexPath]; - cell.labelTitle.text = keyboardManagerProperties[indexPath.section][indexPath.row]; - cell.labelSubtitle.text = keyboardManagerPropertyDetails[indexPath.section][indexPath.row]; + SwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SwitchTableViewCell class])]; + cell.labelTitle.text = [[keyboardManagerProperties objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; + cell.labelSubtitle.text = [[keyboardManagerPropertyDetails objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; cell.switchEnable.on = [[IQKeyboardManager sharedManager] canAdjustTextView]; [cell.switchEnable removeTarget:nil action:NULL forControlEvents:UIControlEventAllEvents]; [cell.switchEnable addTarget:self action:@selector(canAdjustTextViewAction:) forControlEvents:UIControlEventValueChanged]; @@ -335,9 +336,9 @@ { case 0: { - SwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SwitchTableViewCell class]) forIndexPath:indexPath]; - cell.labelTitle.text = keyboardManagerProperties[indexPath.section][indexPath.row]; - cell.labelSubtitle.text = keyboardManagerPropertyDetails[indexPath.section][indexPath.row]; + SwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SwitchTableViewCell class])]; + cell.labelTitle.text = [[keyboardManagerProperties objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; + cell.labelSubtitle.text = [[keyboardManagerPropertyDetails objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; cell.switchEnable.on = [[IQKeyboardManager sharedManager] overrideKeyboardAppearance]; [cell.switchEnable removeTarget:nil action:NULL forControlEvents:UIControlEventAllEvents]; [cell.switchEnable addTarget:self action:@selector(overrideKeyboardAppearanceAction:) forControlEvents:UIControlEventValueChanged]; @@ -346,9 +347,9 @@ break; case 1: { - NavigationTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([NavigationTableViewCell class]) forIndexPath:indexPath]; - cell.labelTitle.text = keyboardManagerProperties[indexPath.section][indexPath.row]; - cell.labelSubtitle.text = keyboardManagerPropertyDetails[indexPath.section][indexPath.row]; + NavigationTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([NavigationTableViewCell class])]; + cell.labelTitle.text = [[keyboardManagerProperties objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; + cell.labelSubtitle.text = [[keyboardManagerPropertyDetails objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; return cell; } break; @@ -361,9 +362,9 @@ { case 0: { - SwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SwitchTableViewCell class]) forIndexPath:indexPath]; - cell.labelTitle.text = keyboardManagerProperties[indexPath.section][indexPath.row]; - cell.labelSubtitle.text = keyboardManagerPropertyDetails[indexPath.section][indexPath.row]; + SwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SwitchTableViewCell class])]; + cell.labelTitle.text = [[keyboardManagerProperties objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; + cell.labelSubtitle.text = [[keyboardManagerPropertyDetails objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; cell.switchEnable.on = [[IQKeyboardManager sharedManager] shouldResignOnTouchOutside]; [cell.switchEnable removeTarget:nil action:NULL forControlEvents:UIControlEventAllEvents]; [cell.switchEnable addTarget:self action:@selector(shouldResignOnTouchOutsideAction:) forControlEvents:UIControlEventValueChanged]; @@ -379,9 +380,9 @@ { case 0: { - SwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SwitchTableViewCell class]) forIndexPath:indexPath]; - cell.labelTitle.text = keyboardManagerProperties[indexPath.section][indexPath.row]; - cell.labelSubtitle.text = keyboardManagerPropertyDetails[indexPath.section][indexPath.row]; + SwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SwitchTableViewCell class])]; + cell.labelTitle.text = [[keyboardManagerProperties objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; + cell.labelSubtitle.text = [[keyboardManagerPropertyDetails objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; cell.switchEnable.on = [[IQKeyboardManager sharedManager] shouldPlayInputClicks]; [cell.switchEnable removeTarget:nil action:NULL forControlEvents:UIControlEventAllEvents]; [cell.switchEnable addTarget:self action:@selector(shouldPlayInputClicksAction:) forControlEvents:UIControlEventValueChanged]; @@ -397,9 +398,9 @@ { case 0: { - SwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SwitchTableViewCell class]) forIndexPath:indexPath]; - cell.labelTitle.text = keyboardManagerProperties[indexPath.section][indexPath.row]; - cell.labelSubtitle.text = keyboardManagerPropertyDetails[indexPath.section][indexPath.row]; + SwitchTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([SwitchTableViewCell class])]; + cell.labelTitle.text = [[keyboardManagerProperties objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; + cell.labelSubtitle.text = [[keyboardManagerPropertyDetails objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; cell.switchEnable.on = [[IQKeyboardManager sharedManager] shouldAdoptDefaultKeyboardAnimation]; [cell.switchEnable removeTarget:nil action:NULL forControlEvents:UIControlEventAllEvents]; [cell.switchEnable addTarget:self action:@selector(shouldAdoptDefaultKeyboardAnimation:) forControlEvents:UIControlEventValueChanged]; @@ -433,16 +434,16 @@ if (selectedIndexPathForOptions.section == 1 && selectedIndexPathForOptions.row == 1) { controller.title = @"Toolbar Manage Behaviour"; - controller.options = @[@"IQAutoToolbar By Subviews",@"IQAutoToolbar By Tag",@"IQAutoToolbar By Position"]; + controller.options = [NSArray arrayWithObjects:@"IQAutoToolbar By Subviews",@"IQAutoToolbar By Tag",@"IQAutoToolbar By Position",nil]; controller.selectedIndex = [[IQKeyboardManager sharedManager] toolbarManageBehaviour]; } else if (selectedIndexPathForOptions.section == 1 && selectedIndexPathForOptions.row == 4) { controller.title = @"Fonts"; - controller.options = @[@"Bold System Font",@"Italic system font",@"Regular"]; + controller.options = [NSArray arrayWithObjects:@"Bold System Font",@"Italic system font",@"Regular",nil]; - NSArray *fonts = @[[UIFont boldSystemFontOfSize:12.0],[UIFont italicSystemFontOfSize:12],[UIFont systemFontOfSize:12]]; + NSArray *fonts = [NSArray arrayWithObjects:[UIFont boldSystemFontOfSize:12.0],[UIFont italicSystemFontOfSize:12],[UIFont systemFontOfSize:12],nil]; UIFont *placeholderFont = [[IQKeyboardManager sharedManager] placeholderFont]; @@ -454,7 +455,7 @@ else if (selectedIndexPathForOptions.section == 3 && selectedIndexPathForOptions.row == 1) { controller.title = @"Keyboard Appearance"; - controller.options = @[@"UIKeyboardAppearance Default",@"UIKeyboardAppearance Dark",@"UIKeyboardAppearance Light"]; + controller.options = [NSArray arrayWithObjects:@"UIKeyboardAppearance Default",@"UIKeyboardAppearance Dark",@"UIKeyboardAppearance Light",nil]; controller.selectedIndex = [[IQKeyboardManager sharedManager] keyboardAppearance]; } } @@ -468,9 +469,9 @@ } else if (selectedIndexPathForOptions.section == 1 && selectedIndexPathForOptions.row == 4) { - NSArray *fonts = @[[UIFont boldSystemFontOfSize:12.0],[UIFont italicSystemFontOfSize:12],[UIFont systemFontOfSize:12]]; + NSArray *fonts = [NSArray arrayWithObjects:[UIFont boldSystemFontOfSize:12.0],[UIFont italicSystemFontOfSize:12],[UIFont systemFontOfSize:12],nil]; - [[IQKeyboardManager sharedManager] setPlaceholderFont:fonts[index]]; + [[IQKeyboardManager sharedManager] setPlaceholderFont:[fonts objectAtIndex:index]]; } else if (selectedIndexPathForOptions.section == 3 && selectedIndexPathForOptions.row == 1) { diff --git a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/SpecialCaseViewController.m b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/SpecialCaseViewController.m index 2a1c4a5..8d3d9ba 100644 --- a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/SpecialCaseViewController.m +++ b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/SpecialCaseViewController.m @@ -7,6 +7,8 @@ @interface SpecialCaseViewController () +-(void)updateUI; + @end @implementation SpecialCaseViewController diff --git a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/StepperTableViewCell.m b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/StepperTableViewCell.m index 8aad795..97f8adb 100644 --- a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/StepperTableViewCell.m +++ b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/StepperTableViewCell.m @@ -10,6 +10,8 @@ @implementation StepperTableViewCell +@synthesize labelTitle, labelSubtitle, stepper, labelStepperValue; + - (void)awakeFromNib { [super awakeFromNib]; diff --git a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/SwitchTableViewCell.m b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/SwitchTableViewCell.m index 017b6e2..d729f6b 100644 --- a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/SwitchTableViewCell.m +++ b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/SwitchTableViewCell.m @@ -9,6 +9,7 @@ #import "SwitchTableViewCell.h" @implementation SwitchTableViewCell +@synthesize labelTitle, labelSubtitle, switchEnable; - (void)awakeFromNib { diff --git a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/TableViewInContainerViewController.m b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/TableViewInContainerViewController.m index b5a264f..09b4496 100644 --- a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/TableViewInContainerViewController.m +++ b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/TableViewInContainerViewController.m @@ -38,7 +38,7 @@ } UITextField *textField = (UITextField *)[cell.contentView viewWithTag:123]; - textField.placeholder = [NSString stringWithFormat:@"Cell %@", @(indexPath.row)]; + textField.placeholder = [NSString stringWithFormat:@"Cell %@",[NSNumber numberWithInteger:indexPath.row]]; return cell; } diff --git a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/TextFieldViewController.m b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/TextFieldViewController.m index 7ab9588..2f09525 100644 --- a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/TextFieldViewController.m +++ b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/TextFieldViewController.m @@ -7,7 +7,12 @@ #import "IQKeyboardReturnKeyHandler.h" #import "IQDropDownTextField.h" #import "IQUIView+IQKeyboardToolbar.h" -#import "IQKeyboardManagerConstantsInternal.h" + +@interface TextFieldViewController () + +-(void)refreshUI; + +@end @implementation TextFieldViewController { @@ -58,7 +63,7 @@ [returnKeyHandler setLastTextFieldReturnKeyType:UIReturnKeyDone]; returnKeyHandler.toolbarManageBehaviour = IQAutoToolbarByPosition; - [dropDownTextField setItemList:@[@"Zero Line Of Code", + [dropDownTextField setItemList:[NSArray arrayWithObjects:@"Zero Line Of Code", @"No More UIScrollView", @"No More Subclasses", @"No More Manual Work", @@ -74,9 +79,7 @@ @"Auto adjust textView's height ", @"Adopt tintColor from textField", @"Customize keyboardAppearance", - @"play sound on next/prev/done", - ]]; - + @"play sound on next/prev/done",nil]]; } -(void)viewWillAppear:(BOOL)animated @@ -118,7 +121,7 @@ UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:controller]; navigationController.navigationBar.tintColor = self.navigationController.navigationBar.tintColor; -#if IQ_IS_XCODE_5_OR_GREATER +#ifdef NSFoundationVersionNumber_iOS_6_1 navigationController.navigationBar.barTintColor = self.navigationController.navigationBar.barTintColor; #endif navigationController.navigationBar.titleTextAttributes = self.navigationController.navigationBar.titleTextAttributes; diff --git a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/TextSelectionViewController.m b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/TextSelectionViewController.m index 877c409..f4124c0 100755 --- a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/TextSelectionViewController.m +++ b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/TextSelectionViewController.m @@ -12,14 +12,17 @@ @implementation TextSelectionViewController +@synthesize data = _data; +@synthesize tableView = _tableView; + - (void)viewDidLoad { [super viewDidLoad]; self.tableView.delegate = self; self.tableView.dataSource = self; - _data = @[@"Hello", @"This is a demo code", @"Issue #56", @"With mutiple cells", @"And some useless text.", + _data = [NSArray arrayWithObjects:@"Hello", @"This is a demo code", @"Issue #56", @"With mutiple cells", @"And some useless text.", @"Hello", @"This is a demo code", @"Issue #56", @"With mutiple cells", @"And some useless text.", - @"Hello", @"This is a demo code", @"Issue #56", @"With mutiple cells", @"And some useless text."]; + @"Hello", @"This is a demo code", @"Issue #56", @"With mutiple cells", @"And some useless text.",nil]; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath @@ -47,7 +50,7 @@ UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(5,7,135,30)]; textView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; textView.backgroundColor = [UIColor clearColor]; - textView.text = _data[indexPath.row]; + textView.text = [_data objectAtIndex:indexPath.row]; textView.dataDetectorTypes = UIDataDetectorTypeAll; textView.scrollEnabled = NO; textView.editable = NO; diff --git a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/TextViewSpecialCaseViewController.m b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/TextViewSpecialCaseViewController.m index cd01097..724cb1e 100644 --- a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/TextViewSpecialCaseViewController.m +++ b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/TextViewSpecialCaseViewController.m @@ -5,6 +5,12 @@ #import "TextViewSpecialCaseViewController.h" #import "IQKeyboardManager.h" +@interface TextViewSpecialCaseViewController () + +-(void)refreshUI; + +@end + @implementation TextViewSpecialCaseViewController -(IBAction)canAdjustTextView:(UIBarButtonItem*)barButton diff --git a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/ViewController.m b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/ViewController.m index cdc93cd..2551c11 100644 --- a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/ViewController.m +++ b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/ViewController.m @@ -14,6 +14,9 @@ - (IBAction)shareClicked:(UIBarButtonItem *)sender { + +#ifdef NSFoundationVersionNumber_iOS_5_1 + NSString *shareString = @"IQKeyboardManager is really great control for iOS developer to manage keyboard-textField."; UIImage *shareImage = [UIImage imageNamed:@"IQKeyboardManagerScreenshot"]; NSURL *youtubeUrl = [NSURL URLWithString:@"http://youtu.be/6nhLw6hju2A"]; @@ -29,6 +32,7 @@ UIActivityTypeSaveToCameraRoll]; controller.excludedActivityTypes = excludedActivities; [self presentViewController:controller animated:YES completion:nil]; +#endif } -(void)viewDidLoad @@ -54,11 +58,15 @@ return (toInterfaceOrientation == UIInterfaceOrientationPortrait); } +#ifdef NSFoundationVersionNumber_iOS_5_1 + -(NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; } +#endif + - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { return UIInterfaceOrientationPortrait; diff --git a/README.md b/README.md index 1e572ec..f22ad15 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ alt="IQKeyboardManager Demo Video" width="480" height="360" border="10" /> Minimum iOS Target: iOS 5.0 -Minimum Xcode Version: Xcode 5.0 +Minimum Xcode Version: Xcode 4.2 #### Demo Project:- From 20c6dbe6daf2eaff2d501202c90e5fc77f2beafb Mon Sep 17 00:00:00 2001 From: hackiftekhar Date: Wed, 8 Apr 2015 16:16:27 +0530 Subject: [PATCH 04/13] Updated Documentation --- IQKeyBoardManager/Categories/IQNSArray+Sort.h | 16 +- IQKeyBoardManager/Categories/IQNSArray+Sort.m | 13 +- .../Categories/IQUIView+Hierarchy.h | 97 +++--- .../Categories/IQUIView+Hierarchy.m | 122 +------- .../Categories/IQUIWindow+Hierarchy.h | 16 +- .../Constants/IQKeyboardManagerConstants.h | 48 +-- IQKeyBoardManager/IQKeyboardManager.h | 228 ++++++-------- IQKeyBoardManager/IQKeyboardManager.m | 31 +- .../IQKeyboardReturnKeyHandler.h | 54 ++-- .../IQSegmentedNextPrevious.h | 27 +- IQKeyBoardManager/IQTextView/IQTextView.h | 8 +- IQKeyBoardManager/IQToolbar/IQBarButtonItem.h | 5 +- .../IQToolbar/IQTitleBarButtonItem.h | 17 +- IQKeyBoardManager/IQToolbar/IQToolbar.h | 16 +- .../IQToolbar/IQUIView+IQKeyboardToolbar.h | 295 +++++++++++++----- KeyboardTextFieldDemo/.DS_Store | Bin 15364 -> 15364 bytes 16 files changed, 474 insertions(+), 519 deletions(-) diff --git a/IQKeyBoardManager/Categories/IQNSArray+Sort.h b/IQKeyBoardManager/Categories/IQNSArray+Sort.h index 1052603..650b861 100644 --- a/IQKeyBoardManager/Categories/IQNSArray+Sort.h +++ b/IQKeyBoardManager/Categories/IQNSArray+Sort.h @@ -24,23 +24,21 @@ #import /** - @category NSArray (IQ_NSArray_Sort) - - @abstract UIView.subviews sorting category. + UIView.subviews sorting category. */ @interface NSArray (IQ_NSArray_Sort) +///-------------- +/// @name Sorting +///-------------- + /** - @method sortedArrayByTag - - @return Returns the array by sorting the UIView's by their tag property. + Returns the array by sorting the UIView's by their tag property. */ - (NSArray*)sortedArrayByTag; /** - @method sortedArrayByTag - - @return Returns the array by sorting the UIView's by their tag property. + Returns the array by sorting the UIView's by their tag property. */ - (NSArray*)sortedArrayByPosition; diff --git a/IQKeyBoardManager/Categories/IQNSArray+Sort.m b/IQKeyBoardManager/Categories/IQNSArray+Sort.m index 106cb7f..d57b0a3 100644 --- a/IQKeyBoardManager/Categories/IQNSArray+Sort.m +++ b/IQKeyBoardManager/Categories/IQNSArray+Sort.m @@ -49,14 +49,19 @@ { return [self sortedArrayUsingComparator:^NSComparisonResult(UIView *view1, UIView *view2) { - if (view1.IQ_y < view2.IQ_y) return NSOrderedAscending; + CGFloat x1 = CGRectGetMinX(view1.frame); + CGFloat y1 = CGRectGetMinY(view1.frame); + CGFloat x2 = CGRectGetMinX(view2.frame); + CGFloat y2 = CGRectGetMinY(view2.frame); - else if (view1.IQ_y > view2.IQ_y) return NSOrderedDescending; + if (y1 < y2) return NSOrderedAscending; + + else if (y1 > y2) return NSOrderedDescending; //Else both y are same so checking for x positions - else if (view1.IQ_x < view2.IQ_x) return NSOrderedAscending; + else if (x1 < x2) return NSOrderedAscending; - else if (view1.IQ_x > view2.IQ_x) return NSOrderedDescending; + else if (x1 > x2) return NSOrderedDescending; else return NSOrderedSame; }]; diff --git a/IQKeyBoardManager/Categories/IQUIView+Hierarchy.h b/IQKeyBoardManager/Categories/IQUIView+Hierarchy.h index aae9b82..2632f30 100644 --- a/IQKeyBoardManager/Categories/IQUIView+Hierarchy.h +++ b/IQKeyBoardManager/Categories/IQUIView+Hierarchy.h @@ -27,93 +27,91 @@ @class UICollectionView, UIScrollView, UITableView, NSArray; /** - @category UIView (IQ_UIView_Hierarchy) - - @abstract UIView hierarchy category. + UIView hierarchy category. */ @interface UIView (IQ_UIView_Hierarchy) +///------------------------------ +/// @name canBecomeFirstResponder +///------------------------------ + /** - @property isAskingCanBecomeFirstResponder - - @abstract Returns YES if IQKeyboardManager asking for `canBecomeFirstResponder. Useful when doing custom work in `textFieldShouldBeginEditing:` delegate. + Returns YES if IQKeyboardManager asking for `canBecomeFirstResponder. Useful when doing custom work in `textFieldShouldBeginEditing:` delegate. */ @property (nonatomic, readonly) BOOL isAskingCanBecomeFirstResponder; +///---------------------- +/// @name viewControllers +///---------------------- + /** - @property viewController - - @abstract Returns the UIViewController object that manages the receiver. + Returns the UIViewController object that manages the receiver. */ @property (nonatomic, readonly, strong) UIViewController *viewController; /** - @property topMostController - - @abstract Returns the topMost UIViewController object in hierarchy. + Returns the topMost UIViewController object in hierarchy. */ @property (nonatomic, readonly, strong) UIViewController *topMostController; +///----------------------------------- +/// @name Superviews/Subviews/Siglings +///----------------------------------- + /** - @method superviewOfClassType: - - @return Returns the superView of provided class type. + Returns the superView of provided class type. */ -(UIView*)superviewOfClassType:(Class)classType; /** - @property responderSiblings - - @abstract returns all siblings of the receiver which canBecomeFirstResponder. + Returns all siblings of the receiver which canBecomeFirstResponder. */ @property (nonatomic, readonly, copy) NSArray *responderSiblings; /** - @property deepResponderViews - - @abstract returns all deep subViews of the receiver which canBecomeFirstResponder. + Returns all deep subViews of the receiver which canBecomeFirstResponder. */ @property (nonatomic, readonly, copy) NSArray *deepResponderViews; +///------------------------- +/// @name Special TextFields +///------------------------- + /** - @property isSearchBarTextField - - @abstract returns YES if the receiver object is UISearchBarTextField, otherwise return NO. + Returns YES if the receiver object is UISearchBarTextField, otherwise return NO. */ @property (nonatomic, getter=isSearchBarTextField, readonly) BOOL searchBarTextField; /** - @property isAlertViewTextField - - @abstract returns YES if the receiver object is UIAlertSheetTextField, otherwise return NO. + Returns YES if the receiver object is UIAlertSheetTextField, otherwise return NO. */ @property (nonatomic, getter=isAlertViewTextField, readonly) BOOL alertViewTextField; +///---------------- +/// @name Transform +///---------------- + /** - @method convertTransformToView - - @return returns current view transform with respect to the 'toView'. + Returns current view transform with respect to the 'toView'. */ -(CGAffineTransform)convertTransformToView:(UIView*)toView; +///----------------- +/// @name Hierarchy +///----------------- + /** - @property subHierarchy - - @abstract Returns a string that represent the information about it's subview's hierarchy. You can use this method to debug the subview's positions. + Returns a string that represent the information about it's subview's hierarchy. You can use this method to debug the subview's positions. */ @property (nonatomic, readonly, copy) NSString *subHierarchy; /** - @property superHierarchy - - @abstract Returns an string that represent the information about it's upper hierarchy. You can use this method to debug the superview's positions. + Returns an string that represent the information about it's upper hierarchy. You can use this method to debug the superview's positions. */ @property (nonatomic, readonly, copy) NSString *superHierarchy; /** - @property debugHierarchy - - @abstract Returns an string that represent the information about it's frame positions. You can use this method to debug self positions. + Returns an string that represent the information about it's frame positions. You can use this method to debug self positions. */ @property (nonatomic, readonly, copy) NSString *debugHierarchy; @@ -121,29 +119,12 @@ /** - @category UIView (IQ_UIView_Frame) - - @abstract UIView frame category. + NSObject category to used for logging purposes */ -@interface UIView (IQ_UIView_Frame) - -@property (nonatomic, assign) CGPoint IQ_origin; -@property (nonatomic, assign) CGSize IQ_size; -@property (nonatomic, assign) CGFloat IQ_x, IQ_y, IQ_width, IQ_height; -@property (nonatomic, assign) CGFloat IQ_left, IQ_right, IQ_top, IQ_bottom; -@property (nonatomic, assign) CGFloat IQ_centerX; -@property (nonatomic, assign) CGFloat IQ_centerY; -@property (nonatomic, readonly) CGPoint IQ_boundsCenter; - -@end - - @interface NSObject (IQ_Logging) /** - @property _IQDescription - - @abstract Short description for logging purpose. + Short description for logging purpose. */ @property (nonatomic, readonly, copy) NSString *_IQDescription; diff --git a/IQKeyBoardManager/Categories/IQUIView+Hierarchy.m b/IQKeyBoardManager/Categories/IQUIView+Hierarchy.m index ef730ca..30555d1 100644 --- a/IQKeyBoardManager/Categories/IQUIView+Hierarchy.m +++ b/IQKeyBoardManager/Categories/IQUIView+Hierarchy.m @@ -180,11 +180,21 @@ Class UISearchBarTextFieldClass; //UISearchBar //subviews are returning in opposite order. So I sorted it according the frames 'y'. NSArray *subViews = [self.subviews sortedArrayUsingComparator:^NSComparisonResult(UIView *view1, UIView *view2) { - if (view1.IQ_y < view2.IQ_y) return NSOrderedAscending; + CGFloat x1 = CGRectGetMinX(view1.frame); + CGFloat y1 = CGRectGetMinY(view1.frame); + CGFloat x2 = CGRectGetMinX(view2.frame); + CGFloat y2 = CGRectGetMinY(view2.frame); - else if (view1.IQ_y > view2.IQ_y) return NSOrderedDescending; + if (y1 < y2) return NSOrderedAscending; - else return NSOrderedSame; + else if (y1 > y2) return NSOrderedDescending; + + //Else both y are same so checking for x positions + else if (x1 < x2) return NSOrderedAscending; + + else if (x1 > x2) return NSOrderedDescending; + + else return NSOrderedSame; }]; for (UITextField *textField in subViews) @@ -290,7 +300,7 @@ Class UISearchBarTextFieldClass; //UISearchBar { NSMutableString *debugInfo = [[NSMutableString alloc] init]; - [debugInfo appendFormat:@"%@: ( %.0f, %.0f, %.0f, %.0f )",NSStringFromClass([self class]),self.IQ_x,self.IQ_y,self.IQ_width,self.IQ_height]; + [debugInfo appendFormat:@"%@: ( %.0f, %.0f, %.0f, %.0f )",NSStringFromClass([self class]), CGRectGetMinX(self.frame), CGRectGetMinY(self.frame), CGRectGetWidth(self.frame), CGRectGetHeight(self.frame)]; if ([self isKindOfClass:[UIScrollView class]]) { @@ -318,110 +328,6 @@ Class UISearchBarTextFieldClass; //UISearchBar @end -@implementation UIView (IQ_UIView_Frame) - --(CGFloat)IQ_x { return CGRectGetMinX(self.frame); } --(CGFloat)IQ_y { return CGRectGetMinY(self.frame); } --(CGFloat)IQ_width { return CGRectGetWidth(self.frame); } --(CGFloat)IQ_height { return CGRectGetHeight(self.frame); } --(CGPoint)IQ_origin { return self.frame.origin; } --(CGSize)IQ_size { return self.frame.size; } --(CGFloat)IQ_left { return CGRectGetMinX(self.frame); } --(CGFloat)IQ_right { return CGRectGetMaxX(self.frame); } --(CGFloat)IQ_top { return CGRectGetMinY(self.frame); } --(CGFloat)IQ_bottom { return CGRectGetMaxY(self.frame); } --(CGFloat)IQ_centerX { return self.center.x; } --(CGFloat)IQ_centerY { return self.center.y; } --(CGPoint)IQ_boundsCenter { return CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds)); }; - --(void)setIQ_x:(CGFloat)IQ_x -{ - CGRect frame = self.frame; - frame.origin.x = IQ_x; - self.frame = frame; -} - --(void)setIQ_y:(CGFloat)IQ_y -{ - CGRect frame = self.frame; - frame.origin.y = IQ_y; - self.frame = frame; -} - --(void)setIQ_width:(CGFloat)IQ_width -{ - CGRect frame = self.frame; - frame.size.width = IQ_width; - self.frame = frame; -} - --(void)setIQ_height:(CGFloat)IQ_height -{ - CGRect frame = self.frame; - frame.size.height = IQ_height; - self.frame = frame; -} - --(void)setIQ_origin:(CGPoint)IQ_origin -{ - CGRect frame = self.frame; - frame.origin = IQ_origin; - self.frame = frame; -} - --(void)setIQ_size:(CGSize)IQ_size -{ - CGRect frame = self.frame; - frame.size = IQ_size; - self.frame = frame; -} - --(void)setIQ_left:(CGFloat)IQ_left -{ - CGRect frame = self.frame; - frame.origin.x = IQ_left; - frame.size.width = MAX(self.IQ_right-IQ_left, 0); - self.frame = frame; -} - --(void)setIQ_right:(CGFloat)IQ_right -{ - CGRect frame = self.frame; - frame.size.width = MAX(IQ_right-self.IQ_left, 0); - self.frame = frame; -} - --(void)setIQ_top:(CGFloat)IQ_top -{ - CGRect frame = self.frame; - frame.origin.y = IQ_top; - frame.size.height = MAX(self.IQ_bottom-IQ_top, 0); - self.frame = frame; -} - --(void)setIQ_bottom:(CGFloat)IQ_bottom -{ - CGRect frame = self.frame; - frame.size.height = MAX(IQ_bottom-self.IQ_top, 0); - self.frame = frame; -} - --(void)setIQ_centerX:(CGFloat)IQ_centerX -{ - CGPoint center = self.center; - center.x = IQ_centerX; - self.center = center; -} - --(void)setIQ_centerY:(CGFloat)IQ_centerY -{ - CGPoint center = self.center; - center.y = IQ_centerY; - self.center = center; -} - -@end - @implementation NSObject (IQ_Logging) diff --git a/IQKeyBoardManager/Categories/IQUIWindow+Hierarchy.h b/IQKeyBoardManager/Categories/IQUIWindow+Hierarchy.h index 3140011..47c8da3 100644 --- a/IQKeyBoardManager/Categories/IQUIWindow+Hierarchy.h +++ b/IQKeyBoardManager/Categories/IQUIWindow+Hierarchy.h @@ -26,23 +26,21 @@ @class UIViewController; /** - @category UIWindow (IQ_UIWindow_Hierarchy) - - @abstract UIWindow hierarchy category. + UIWindow hierarchy category. */ @interface UIWindow (IQ_UIWindow_Hierarchy) +///---------------------- +/// @name viewControllers +///---------------------- + /** - @method topMostController - - @return Returns the current Top Most ViewController in hierarchy. + Returns the current Top Most ViewController in hierarchy. */ @property (nonatomic, readonly, strong) UIViewController *topMostController; /** - @method currentViewController - - @return Returns the topViewController in stack of topMostController. + Returns the topViewController in stack of topMostController. */ @property (nonatomic, readonly, strong) UIViewController *currentViewController; diff --git a/IQKeyBoardManager/Constants/IQKeyboardManagerConstants.h b/IQKeyBoardManager/Constants/IQKeyboardManagerConstants.h index 643c123..07f372f 100644 --- a/IQKeyBoardManager/Constants/IQKeyboardManagerConstants.h +++ b/IQKeyBoardManager/Constants/IQKeyboardManagerConstants.h @@ -26,49 +26,59 @@ #import -/* Set IQKEYBOARDMANAGER_DEBUG=1 in preprocessor macros under build settings to enable debugging.*/ +///---------------- +/// @name Debugging +///---------------- /** - @enum IQAutoToolbarManageBehaviour - - @abstract AutoToolbar manage settings. - - @const IQAutoToolbarBySubviews Creates Toolbar according to subview's hirarchy of Textfield's in view. - - @const IQAutoToolbarByTag Creates Toolbar according to tag property of TextField's. - - @const IQAutoToolbarByPosition Creates Toolbar according to the y,x position of textField in it's superview coordinate. + Set IQKEYBOARDMANAGER_DEBUG=1 in preprocessor macros under build settings to enable debugging. */ -#ifndef NS_ENUM +///----------------------------------- +/// @name IQAutoToolbarManageBehaviour +///----------------------------------- +/** + `IQAutoToolbarBySubviews` + Creates Toolbar according to subview's hirarchy of Textfield's in view. + + `IQAutoToolbarByTag` + Creates Toolbar according to tag property of TextField's. + + `IQAutoToolbarByPosition` + Creates Toolbar according to the y,x position of textField in it's superview coordinate. + */ +#ifndef NS_ENUM typedef enum IQAutoToolbarManageBehaviour { IQAutoToolbarBySubviews, IQAutoToolbarByTag, IQAutoToolbarByPosition, }IQAutoToolbarManageBehaviour; - #else - typedef NS_ENUM(NSInteger, IQAutoToolbarManageBehaviour) { IQAutoToolbarBySubviews, IQAutoToolbarByTag, IQAutoToolbarByPosition, }; - #endif +///------------------- +/// @name Localization +///------------------- + #define IQLocalizedString(key, comment) [[NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"IQKeyboardManager" ofType:@"bundle"]] localizedStringForKey:(key) value:@"" table:@"IQKeyboardManager"] -#endif /* XCode 5.0 Compatibility for NS_DESIGNATED_INITIALIZER*/ #ifndef NS_DESIGNATED_INITIALIZER -#if __has_attribute(objc_designated_initializer) -#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) -#else -#define NS_DESIGNATED_INITIALIZER + #if __has_attribute(objc_designated_initializer) + #define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) + #else + #define NS_DESIGNATED_INITIALIZER + #endif #endif + + #endif /* diff --git a/IQKeyBoardManager/IQKeyboardManager.h b/IQKeyBoardManager/IQKeyboardManager.h index 59a6f1c..7160fa1 100755 --- a/IQKeyBoardManager/IQKeyboardManager.h +++ b/IQKeyBoardManager/IQKeyboardManager.h @@ -32,263 +32,215 @@ #if !(__has_feature(objc_instancetype)) - #define instancetype id +#define instancetype id #endif @class UIFont; -/** @const kIQDoneButtonToolbarTag Default tag for toolbar with Done button -1002. */ -extern NSInteger const kIQDoneButtonToolbarTag; -/* @const kIQPreviousNextButtonToolbarTag Default tag for toolbar with Previous/Next buttons -1005. */ -extern NSInteger const kIQPreviousNextButtonToolbarTag; - - /** - @author Iftekhar Qurashi - - @related hack.iftekhar@gmail.com - - @class IQKeyboardManager - - @abstract Keyboard TextField/TextView Manager. A generic version of KeyboardManagement. https://developer.apple.com/Library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html + Codeless drop-in universal library allows to prevent issues of keyboard sliding up and cover UITextField/UITextView. Neither need to write any code nor any setup required and much more. A generic version of KeyboardManagement. https://developer.apple.com/Library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html */ @interface IQKeyboardManager : NSObject - -/*******************************************/ - - -//UIKeyboard handling +///-------------------------- +/// @name UIKeyboard handling +///-------------------------- /** - @method sharedManager - - @return Returns the default singleton instance. + Returns the default singleton instance. */ + (instancetype)sharedManager; /** - @property enable - - @abstract enable/disable managing distance between keyboard and textField. Default is YES(Enabled when class loads in `+(void)load` method). + Enable/disable managing distance between keyboard and textField. Default is YES(Enabled when class loads in `+(void)load` method). */ @property(nonatomic, assign, getter = isEnabled) BOOL enable; /** - @property keyboardDistanceFromTextField - - @abstract To set keyboard distance from textField. can't be less than zero. Default is 10.0. + To set keyboard distance from textField. can't be less than zero. Default is 10.0. */ @property(nonatomic, assign) CGFloat keyboardDistanceFromTextField; /** - @property preventShowingBottomBlankSpace - - @abstract Prevent keyboard manager to slide up the rootView to more than keyboard height. Default is YES. + Prevent keyboard manager to slide up the rootView to more than keyboard height. Default is YES. */ @property(nonatomic, assign) BOOL preventShowingBottomBlankSpace; - -/*******************************************/ - - -//IQToolbar handling +///------------------------- +/// @name IQToolbar handling +///------------------------- /** - @property enableAutoToolbar - - @abstract Automatic add the IQToolbar functionality. Default is YES. + Automatic add the IQToolbar functionality. Default is YES. */ @property(nonatomic, assign, getter = isEnableAutoToolbar) BOOL enableAutoToolbar; /** - @property toolbarManageStyle - - @abstract AutoToolbar managing behaviour. Default is IQAutoToolbarBySubviews. + AutoToolbar managing behaviour. Default is IQAutoToolbarBySubviews. */ @property(nonatomic, assign) IQAutoToolbarManageBehaviour toolbarManageBehaviour; #ifdef NSFoundationVersionNumber_iOS_6_1 - /** - @property shouldToolbarUsesTextFieldTintColor - - @abstract If YES, then uses textField's tintColor property for IQToolbar, otherwise tint color is black. Default is NO. + If YES, then uses textField's tintColor property for IQToolbar, otherwise tint color is black. Default is NO. */ -@property(nonatomic, assign) BOOL shouldToolbarUsesTextFieldTintColor NS_AVAILABLE_IOS(7_0); - +@property(nonatomic, assign) BOOL shouldToolbarUsesTextFieldTintColor; #endif /** - @property shouldShowTextFieldPlaceholder - - @abstract If YES, then it add the textField's placeholder text on IQToolbar. Default is YES. + If YES, then it add the textField's placeholder text on IQToolbar. Default is YES. */ @property(nonatomic, assign) BOOL shouldShowTextFieldPlaceholder; /** - @property placeholderFont - - @abstract Placeholder Font. Default is nil. + Placeholder Font. Default is nil. */ @property(nonatomic, strong) UIFont *placeholderFont; - -/*******************************************/ - - -//UITextView handling +///-------------------------- +/// @name UITextView handling +///-------------------------- /** - @property canAdjustTextView - - @abstract Adjust textView's frame when it is too big in height. Default is NO. + Adjust textView's frame when it is too big in height. Default is NO. */ @property(nonatomic, assign) BOOL canAdjustTextView; /** - @property shouldFixTextViewClip - - @abstract Adjust textView's contentInset to fix fix for iOS 7.0.x - http://stackoverflow.com/questions/18966675/uitextview-in-ios7-clips-the-last-line-of-text-string Default is YES. + Adjust textView's contentInset to fix fix for iOS 7.0.x - http://stackoverflow.com/questions/18966675/uitextview-in-ios7-clips-the-last-line-of-text-string Default is YES. */ @property(nonatomic, assign) BOOL shouldFixTextViewClip; - -/*******************************************/ - - -//UIKeyboard appearance overriding +///--------------------------------------- +/// @name UIKeyboard appearance overriding +///--------------------------------------- /** - @property overrideKeyboardAppearance - - @abstract Override the keyboardAppearance for all textField/textView. Default is NO. + Override the keyboardAppearance for all textField/textView. Default is NO. */ @property(nonatomic, assign) BOOL overrideKeyboardAppearance; /** - @property keyboardAppearance - - @abstract If overrideKeyboardAppearance is YES, then all the textField keyboardAppearance is set using this property. + If overrideKeyboardAppearance is YES, then all the textField keyboardAppearance is set using this property. */ @property(nonatomic, assign) UIKeyboardAppearance keyboardAppearance; - -/*******************************************/ - - -//UITextField/UITextView Resign handling +///--------------------------------------------- +/// @name UITextField/UITextView Resign handling +///--------------------------------------------- /** - @property shouldResignOnTouchOutside - - @abstract Resigns Keyboard on touching outside of UITextField/View. Default is NO. + Resigns Keyboard on touching outside of UITextField/View. Default is NO. */ @property(nonatomic, assign) BOOL shouldResignOnTouchOutside; /** - @method resignFirstResponder - - @abstract Resigns currently first responder field. + Resigns currently first responder field. */ - (void)resignFirstResponder; - -/*******************************************/ - -//UIScrollView handling +///---------------------------- +/// @name UIScrollView handling +///---------------------------- /** - @property shouldRestoreScrollViewContentOffset - - @abstract Restore scrollViewContentOffset when resigning from scrollView. Default is NO. + Restore scrollViewContentOffset when resigning from scrollView. Default is NO. */ @property(nonatomic, assign) BOOL shouldRestoreScrollViewContentOffset; - -//UISound handling +///------------------------------------------------ +/// @name UISound handling +///------------------------------------------------ /** - @property shouldPlayInputClicks - - @abstract If YES, then it plays inputClick sound on next/previous/done click. + If YES, then it plays inputClick sound on next/previous/done click. */ @property(nonatomic, assign) BOOL shouldPlayInputClicks; - -/*******************************************/ - - -//UIAnimation handling +///--------------------------- +/// @name UIAnimation handling +///--------------------------- /** - @property shouldAdoptDefaultKeyboardAnimation + If YES, then uses keyboard default animation curve style to move view, otherwise uses UIViewAnimationOptionCurveEaseInOut animation style. Default is YES. - @abstract If YES, then uses keyboard default animation curve style to move view, otherwise uses UIViewAnimationOptionCurveEaseInOut animation style. Default is YES. - - @discussion Sometimes strange animations may be produced if uses default curve style animation in iOS 7 and changing the textFields very frequently. + @warning Sometimes strange animations may be produced if uses default curve style animation in iOS 7 and changing the textFields very frequently. */ @property(nonatomic, assign) BOOL shouldAdoptDefaultKeyboardAnimation; - -/*******************************************/ - - -//Class Level disabling methods +///------------------------------------ +/// @name Class Level disabling methods +///------------------------------------ /** - @method disableInViewControllerClass: - @method removeDisableInViewControllerClass: + Disable adjusting view in disabledClass - @param disabledClass: Class in which library should not adjust view to show textField. + @param disabledClass Class in which library should not adjust view to show textField. */ -(void)disableInViewControllerClass:(Class)disabledClass; + +/** + Re-enable adjusting textField in disabledClass + + @param disabledClass Class in which library should re-enable adjust view to show textField. + */ -(void)removeDisableInViewControllerClass:(Class)disabledClass; /** - @method disableToolbarInViewControllerClass: - @method removeDisableToolbarInViewControllerClass: + Disable automatic toolbar creation in in toolbarDisabledClass - @param toolbarDisabledClass: Class in which library should not add toolbar over textField. + @param toolbarDisabledClass Class in which library should not add toolbar over textField. */ -(void)disableToolbarInViewControllerClass:(Class)toolbarDisabledClass; + +/** + Re-enable automatic toolbar creation in in toolbarDisabledClass + + @param toolbarDisabledClass Class in which library should re-enable automatic toolbar creation over textField. + */ -(void)removeDisableToolbarInViewControllerClass:(Class)toolbarDisabledClass; /** - @method considerToolbarPreviousNextInViewClass: - @method removeConsiderToolbarPreviousNextInViewClass: + Consider provided customView class as superView of all inner textField for calculating next/previous button logic. - @param toolbarPreviousNextConsideredClass: Custom UIView subclass Class in which library should consider all inner textField as siblings and add next/previous accordingly. + @param toolbarPreviousNextConsideredClass Custom UIView subclass Class in which library should consider all inner textField as siblings and add next/previous accordingly. */ -(void)considerToolbarPreviousNextInViewClass:(Class)toolbarPreviousNextConsideredClass; --(void)removeConsiderToolbarPreviousNextInViewClass:(Class)toolbarPreviousNextConsideredClass; - - -/*******************************************/ - - -//@final. Must not be used for subclassing. /** - @method init + Remove Consideration for provided customView class as superView of all inner textField for calculating next/previous button logic. - @abstract Should create only one instance of class. Should not call init. + @param toolbarPreviousNextConsideredClass Custom UIView subclass Class in which library should remove consideration for all inner textField as superView. + */ +-(void)removeConsiderToolbarPreviousNextInViewClass:(Class)toolbarPreviousNextConsideredClass; + +///------------------------------------------------ +/// @name Must not be used for subclassing. +///------------------------------------------------ + +/** + Should create only one instance of class. Should not call init. */ - (instancetype)init __attribute__((unavailable("init is not available in IQKeyboardManager, Use sharedManager"))) NS_DESIGNATED_INITIALIZER; /** - @method new - - @abstract Should create only one instance of class. Should not call new. + Should create only one instance of class. Should not call new. */ + (instancetype)new __attribute__((unavailable("new is not available in IQKeyboardManager, Use sharedManager"))); - -/*******************************************/ - - @end +///--------------------- +/// @name IQToolbar tags +///--------------------- +/** + Default tag for toolbar with Done button -1002. + */ +extern NSInteger const kIQDoneButtonToolbarTag; +/** + Default tag for toolbar with Previous/Next buttons -1005. + */ +extern NSInteger const kIQPreviousNextButtonToolbarTag; diff --git a/IQKeyBoardManager/IQKeyboardManager.m b/IQKeyBoardManager/IQKeyboardManager.m index 0cbb365..9a36d02 100755 --- a/IQKeyBoardManager/IQKeyboardManager.m +++ b/IQKeyBoardManager/IQKeyboardManager.m @@ -405,7 +405,7 @@ void _IQShowLog(NSString *logString); //frame size needs to be adjusted on iOS8 due to orientation API changes. if (IQ_IS_IOS8_OR_GREATER) { - frame.size = controller.view.IQ_size; + frame.size = controller.view.frame.size; } // If can't get rootViewController then printing warning to user. @@ -459,16 +459,16 @@ void _IQShowLog(NSString *logString); switch (interfaceOrientation) { case UIInterfaceOrientationLandscapeLeft: - move = MIN(CGRectGetMinX(textFieldViewRect)-(CGRectGetWidth(statusBarFrame)+5), CGRectGetMaxX(textFieldViewRect)-(keyWindow.IQ_width-_kbSize.width)); + move = MIN(CGRectGetMinX(textFieldViewRect)-(CGRectGetWidth(statusBarFrame)+5), CGRectGetMaxX(textFieldViewRect)-(CGRectGetWidth(keyWindow.frame)-_kbSize.width)); break; case UIInterfaceOrientationLandscapeRight: - move = MIN(keyWindow.IQ_width-CGRectGetMaxX(textFieldViewRect)-(CGRectGetWidth(statusBarFrame)+5), _kbSize.width-CGRectGetMinX(textFieldViewRect)); + move = MIN(CGRectGetWidth(keyWindow.frame)-CGRectGetMaxX(textFieldViewRect)-(CGRectGetWidth(statusBarFrame)+5), _kbSize.width-CGRectGetMinX(textFieldViewRect)); break; case UIInterfaceOrientationPortrait: - move = MIN(CGRectGetMinY(textFieldViewRect)-(CGRectGetHeight(statusBarFrame)+5), CGRectGetMaxY(textFieldViewRect)-(keyWindow.IQ_height-_kbSize.height)); + move = MIN(CGRectGetMinY(textFieldViewRect)-(CGRectGetHeight(statusBarFrame)+5), CGRectGetMaxY(textFieldViewRect)-(CGRectGetHeight(keyWindow.frame)-_kbSize.height)); break; case UIInterfaceOrientationPortraitUpsideDown: - move = MIN(keyWindow.IQ_height-CGRectGetMaxY(textFieldViewRect)-(CGRectGetHeight(statusBarFrame)+5), _kbSize.height-CGRectGetMinY(textFieldViewRect)); + move = MIN(CGRectGetHeight(keyWindow.frame)-CGRectGetMaxY(textFieldViewRect)-(CGRectGetHeight(statusBarFrame)+5), _kbSize.height-CGRectGetMinY(textFieldViewRect)); break; default: break; @@ -581,13 +581,13 @@ void _IQShowLog(NSString *logString); switch (interfaceOrientation) { case UIInterfaceOrientationLandscapeLeft: - bottom = _kbSize.width-(keyWindow.IQ_width-CGRectGetMaxX(lastScrollViewRect)); + bottom = _kbSize.width-(CGRectGetWidth(keyWindow.frame)-CGRectGetMaxX(lastScrollViewRect)); break; case UIInterfaceOrientationLandscapeRight: bottom = _kbSize.width-CGRectGetMinX(lastScrollViewRect); break; case UIInterfaceOrientationPortrait: - bottom = _kbSize.height-(keyWindow.IQ_height-CGRectGetMaxY(lastScrollViewRect)); + bottom = _kbSize.height-(CGRectGetHeight(keyWindow.frame)-CGRectGetMaxY(lastScrollViewRect)); break; case UIInterfaceOrientationPortraitUpsideDown: bottom = _kbSize.height-CGRectGetMinY(lastScrollViewRect); @@ -600,7 +600,6 @@ void _IQShowLog(NSString *logString); UIEdgeInsets movedInsets = _lastScrollView.contentInset; movedInsets.bottom = MAX(_startingContentInsets.bottom, bottom); -// movedInsets.bottom = MAX(0, (_lastScrollView.contentOffset.y+_lastScrollView.IQ_height)-MAX(_lastScrollView.contentSize.height, _lastScrollView.IQ_height)); _IQShowLog([NSString stringWithFormat:@"%@ old ContentInset : %@",[_lastScrollView _IQDescription], NSStringFromUIEdgeInsets(_lastScrollView.contentInset)]); @@ -626,17 +625,17 @@ void _IQShowLog(NSString *logString); //Added _isTextFieldViewFrameChanged. (Bug ID: #92) if (_canAdjustTextView && [_textFieldView isKindOfClass:[UITextView class]] && _keyboardManagerFlags.isTextFieldViewFrameChanged == NO) { - CGFloat textViewHeight = _textFieldView.IQ_height; + CGFloat textViewHeight = CGRectGetHeight(_textFieldView.frame); switch (interfaceOrientation) { case UIInterfaceOrientationLandscapeLeft: case UIInterfaceOrientationLandscapeRight: - textViewHeight = MIN(textViewHeight, (keyWindow.IQ_width-_kbSize.width-(CGRectGetWidth(statusBarFrame)+5))); + textViewHeight = MIN(textViewHeight, (CGRectGetWidth(keyWindow.frame)-_kbSize.width-(CGRectGetWidth(statusBarFrame)+5))); break; case UIInterfaceOrientationPortrait: case UIInterfaceOrientationPortraitUpsideDown: - textViewHeight = MIN(textViewHeight, (keyWindow.IQ_height-_kbSize.height-(CGRectGetHeight(statusBarFrame)+5))); + textViewHeight = MIN(textViewHeight, (CGRectGetHeight(keyWindow.frame)-_kbSize.height-(CGRectGetHeight(statusBarFrame)+5))); break; default: break; @@ -646,7 +645,9 @@ void _IQShowLog(NSString *logString); _IQShowLog([NSString stringWithFormat:@"%@ Old Frame : %@",[_textFieldView _IQDescription], NSStringFromCGRect(_textFieldView.frame)]); - _textFieldView.IQ_height = textViewHeight; + CGRect textFieldViewRect = _textFieldView.frame; + textFieldViewRect.size.height = textViewHeight; + _textFieldView.frame = textFieldViewRect; _keyboardManagerFlags.isTextFieldViewFrameChanged = YES; _IQShowLog([NSString stringWithFormat:@"%@ New Frame : %@",[_textFieldView _IQDescription], NSStringFromCGRect(_textFieldView.frame)]); @@ -675,10 +676,10 @@ void _IQShowLog(NSString *logString); { case UIInterfaceOrientationLandscapeLeft: case UIInterfaceOrientationLandscapeRight: - minimumY = keyWindow.IQ_width-rootViewRect.size.height-statusBarFrame.size.width-(_kbSize.width-_keyboardDistanceFromTextField); break; + minimumY = CGRectGetWidth(keyWindow.frame)-rootViewRect.size.height-statusBarFrame.size.width-(_kbSize.width-_keyboardDistanceFromTextField); break; case UIInterfaceOrientationPortrait: case UIInterfaceOrientationPortraitUpsideDown: - minimumY = (keyWindow.IQ_height-rootViewRect.size.height-statusBarFrame.size.height)/2-(_kbSize.height-_keyboardDistanceFromTextField); break; + minimumY = (CGRectGetHeight(keyWindow.frame)-rootViewRect.size.height-statusBarFrame.size.height)/2-(_kbSize.height-_keyboardDistanceFromTextField); break; default: break; } @@ -949,7 +950,7 @@ void _IQShowLog(NSString *logString); //frame size needs to be adjusted on iOS8 due to orientation API changes. if (IQ_IS_IOS8_OR_GREATER) { - _topViewBeginRect.size = _rootViewController.view.IQ_size; + _topViewBeginRect.size = _rootViewController.view.frame.size; } //Used UIViewAnimationOptionBeginFromCurrentState to minimize strange animations. diff --git a/IQKeyBoardManager/IQKeyboardReturnKeyHandler.h b/IQKeyBoardManager/IQKeyboardReturnKeyHandler.h index fa54f8a..e99e4ca 100644 --- a/IQKeyBoardManager/IQKeyboardReturnKeyHandler.h +++ b/IQKeyBoardManager/IQKeyboardReturnKeyHandler.h @@ -36,69 +36,67 @@ @class UITextField,UIView, UIViewController; /** - @author Iftekhar Qurashi - - @related hack.iftekhar@gmail.com - - @class IQKeyboardReturnKeyHandler - - @abstract Manages the return key to work like next/done in a view hierarchy. + Manages the return key to work like next/done in a view hierarchy. */ @interface IQKeyboardReturnKeyHandler : NSObject +///---------------------- +/// @name Initializations +///---------------------- + /** - @method initWithViewController - - @abstract Add all the textFields available in UIViewController's view. + Add all the textFields available in UIViewController's view. */ -(instancetype)initWithViewController:(UIViewController*)controller NS_DESIGNATED_INITIALIZER; +///--------------- +/// @name Settings +///--------------- + /** - @method delegate - - @abstract textField's delegates. + Delegate of textField/textView. */ @property(nonatomic, weak) id delegate; /** - @property toolbarManageBehaviour - - @abstract It help to choose the lastTextField instance from sibling responderViews. Default is IQAutoToolbarBySubviews. + It help to choose the lastTextField instance from sibling responderViews. Default is IQAutoToolbarBySubviews. */ @property(nonatomic, assign) IQAutoToolbarManageBehaviour toolbarManageBehaviour; /** - @property lastTextFieldReturnKeyType - - @abstract Set the last textfield return key type. Default is UIReturnKeyDefault. + Set the last textfield return key type. Default is UIReturnKeyDefault. */ @property(nonatomic, assign) UIReturnKeyType lastTextFieldReturnKeyType; +///---------------------------------------------- +/// @name Registering/Unregistering textFieldView +///---------------------------------------------- + /** - @method addTextFieldView + Should pass UITextField/UITextView intance. Assign textFieldView delegate to self, change it's returnKeyType. - @abstract Should pass UITextField/UITextView intance. Assign textFieldView delegate to self, change it's returnKeyType. + @param textFieldView UITextField/UITextView object to register. */ -(void)addTextFieldView:(UIView*)textFieldView; /** - @method removeTextFieldView - - @abstract Should pass UITextField/UITextView intance. Restore it's textFieldView delegate and it's returnKeyType. + Should pass UITextField/UITextView intance. Restore it's textFieldView delegate and it's returnKeyType. + + @param textFieldView UITextField/UITextView object to unregister. */ -(void)removeTextFieldView:(UIView*)textFieldView; /** - @method addResponderFromView + Add all the UITextField/UITextView responderView's. - @abstract Add all the UITextField/UITextView responderView's. + @param UIView object to register all it's responder subviews. */ -(void)addResponderFromView:(UIView*)view; /** - @method removeResponderFromView + Remove all the UITextField/UITextView responderView's. - @abstract Remove all the UITextField/UITextView responderView's. + @param UIView object to unregister all it's responder subviews. */ -(void)removeResponderFromView:(UIView*)view; diff --git a/IQKeyBoardManager/IQSegmentedNextPrevious/IQSegmentedNextPrevious.h b/IQKeyBoardManager/IQSegmentedNextPrevious/IQSegmentedNextPrevious.h index 94d0d88..3850bfd 100644 --- a/IQKeyBoardManager/IQSegmentedNextPrevious/IQSegmentedNextPrevious.h +++ b/IQKeyBoardManager/IQSegmentedNextPrevious/IQSegmentedNextPrevious.h @@ -33,39 +33,28 @@ /** - @class IQSegmentedNextPrevious + Custom SegmentedControl for Previous/Next button. - @deprecated Deprecated in iOS 7 - - @abstract Custom SegmentedControl for Previous/Next button. + @deprecated Deprecated in iOS 7 */ - @interface IQSegmentedNextPrevious : UISegmentedControl /** - @method initWithTarget:previousAction:nextAction: + Initialization function for IQSegmentedNextPrevious. - @abstract initialization function for IQSegmentedNextPrevious. - - @param target: Target object for selector. Usually 'self'. - - @param previousAction: Previous button action name. Usually 'previousAction:(IQSegmentedNextPrevious*)segmentedControl'. - - @param nextAction: Next button action name. Usually 'nextAction:(IQSegmentedNextPrevious*)segmentedControl'. + @param target Target object for selector. Usually 'self'. + @param previousAction Previous button action name. Usually 'previousAction:(IQSegmentedNextPrevious*)segmentedControl'. + @param nextAction Next button action name. Usually 'nextAction:(IQSegmentedNextPrevious*)segmentedControl'. */ - (instancetype)initWithTarget:(id)target previousAction:(SEL)previousAction nextAction:(SEL)nextAction NS_DESIGNATED_INITIALIZER; /** - @method init - - @abstract initWithTarget:previousAction:nextAction should be used. + initWithTarget:previousAction:nextAction should be used. */ - (instancetype)init __attribute__((unavailable("init is not available, should use initWithTarget:previousAction:nextAction instead"))); /** - @method init - - @abstract initWithTarget:previousAction:nextAction should be used. + initWithTarget:previousAction:nextAction should be used. */ + (instancetype)new __attribute__((unavailable("new is not available, should use initWithTarget:previousAction:nextAction instead"))); diff --git a/IQKeyBoardManager/IQTextView/IQTextView.h b/IQKeyBoardManager/IQTextView/IQTextView.h index 3c26257..b2b5715 100644 --- a/IQKeyBoardManager/IQTextView/IQTextView.h +++ b/IQKeyBoardManager/IQTextView/IQTextView.h @@ -26,16 +26,12 @@ #import /** - @class IQTextView - - @abstract UITextView with placeholder support + UITextView with placeholder support */ @interface IQTextView : UITextView /** - @property placeholder - - @abstract To set textView's placeholder text. Default is ni. + Set textView's placeholder text. Default is nil. */ @property(nonatomic,copy) NSString *placeholder; diff --git a/IQKeyBoardManager/IQToolbar/IQBarButtonItem.h b/IQKeyBoardManager/IQToolbar/IQBarButtonItem.h index abe22ea..3374716 100644 --- a/IQKeyBoardManager/IQToolbar/IQBarButtonItem.h +++ b/IQKeyBoardManager/IQToolbar/IQBarButtonItem.h @@ -25,11 +25,8 @@ #import /** - @class IQBarButtonItem - - @abstract IQBarButtonItem used for IQToolbar. + IQBarButtonItem used for IQToolbar. */ @interface IQBarButtonItem : UIBarButtonItem - @end diff --git a/IQKeyBoardManager/IQToolbar/IQTitleBarButtonItem.h b/IQKeyBoardManager/IQToolbar/IQTitleBarButtonItem.h index 5468509..91d0116 100644 --- a/IQKeyBoardManager/IQToolbar/IQTitleBarButtonItem.h +++ b/IQKeyBoardManager/IQToolbar/IQTitleBarButtonItem.h @@ -31,27 +31,20 @@ /** - @author Iftekhar Qurashi - - @related hack.iftekhar@gmail.com - - @class IQTitleBarButtonItem - - @abstract BarButtonItem with title text. + BarButtonItem with title text. */ @interface IQTitleBarButtonItem : IQBarButtonItem /** - @property font - - @abstract font to be used in bar button. Default is (system font 12.0 bold). + Font to be used in bar button. Default is (system font 12.0 bold). */ @property(nonatomic, strong) UIFont *font; /** - @method initWithFrame:title: + Initialize with frame and title. - @abstract initialize with frame and title. + @param frame Initial frame of barButtonItem + @param title Title of barButtonItem. */ -(instancetype)initWithFrame:(CGRect)frame title:(NSString *)title NS_DESIGNATED_INITIALIZER; diff --git a/IQKeyBoardManager/IQToolbar/IQToolbar.h b/IQKeyBoardManager/IQToolbar/IQToolbar.h index 9c22064..b0f9da7 100644 --- a/IQKeyBoardManager/IQToolbar/IQToolbar.h +++ b/IQKeyBoardManager/IQToolbar/IQToolbar.h @@ -24,25 +24,19 @@ #import /** - @class IQToolbar - - @abstract IQToolbar for IQKeyboardManager. + IQToolbar for IQKeyboardManager. */ @interface IQToolbar : UIToolbar /** - @property titleFont - - @abstract title font for toolbar. + Title font for toolbar. */ -@property(nonatomic, strong) UIFont *titleFont; +@property(nonatomic, strong) UIFont *titleFont; /** - @property title - - @abstract toolbar title + Toolbar title */ -@property(nonatomic, strong) NSString *title; +@property(nonatomic, strong) NSString *title; @end diff --git a/IQKeyBoardManager/IQToolbar/IQUIView+IQKeyboardToolbar.h b/IQKeyBoardManager/IQToolbar/IQUIView+IQKeyboardToolbar.h index 423e364..b45a200 100644 --- a/IQKeyBoardManager/IQToolbar/IQUIView+IQKeyboardToolbar.h +++ b/IQKeyBoardManager/IQToolbar/IQUIView+IQKeyboardToolbar.h @@ -27,140 +27,277 @@ @class UIBarButtonItem; /** - @category UIView (IQToolbarAddition) - - @abstract UIView category methods to add IQToolbar on UIKeyboard. + UIView category methods to add IQToolbar on UIKeyboard. */ @interface UIView (IQToolbarAddition) /** - @property shouldHideTitle - - @abstract if shouldHideTitle is YES, then title will not be added to the toolbar. Default to NO. + If shouldHideTitle is YES, then title will not be added to the toolbar. Default to NO. */ @property (assign, nonatomic) BOOL shouldHideTitle; +///----------------------------------------- +/// @name Customised Invocation Registration +///----------------------------------------- + /** - @method setCustomPreviousTarget:action: - @method setCustomNextTarget:action: - @method setCustomDoneTarget:action: + Additional target & action to do get callback action. Note that setting custom `previous` selector doesn't affect native `previous` functionality, this is just used to notifiy user to do additional work according to need. - @abstract Invoke action on target when the toolbar is created using IQKeyboardManager, you may add additional target & action to do get callback action. Note that setting custom previous/next/done selector doesn't affect native next/previous/done functionality, this is just used to notifiy user to do additional work according to your need. + @param target Target object. + @param action Target Selector. */ -(void)setCustomPreviousTarget:(id)target action:(SEL)action; + +/** + Additional target & action to do get callback action. Note that setting custom `next` selector doesn't affect native `next` functionality, this is just used to notifiy user to do additional work according to need. + + @param target Target object. + @param action Target Selector. + */ -(void)setCustomNextTarget:(id)target action:(SEL)action; + +/** + Additional target & action to do get callback action. Note that setting custom `done` selector doesn't affect native `done` functionality, this is just used to notifiy user to do additional work according to need. + + @param target Target object. + @param action Target Selector. + */ -(void)setCustomDoneTarget:(id)target action:(SEL)action; /** - @property previousInvocation - - @abstract customized Invocation to be called on previous arrow action. previousInvocation is internally created using setCustomPreviousTarget: method. + Customized Invocation to be called on previous arrow action. previousInvocation is internally created using setCustomPreviousTarget: method. */ @property (strong, nonatomic) NSInvocation *previousInvocation; /** - @property nextInvocation - - @abstract customized Invocation to be called on next arrow action. nextInvocation is internally created using setCustomNextTarget: method. + Customized Invocation to be called on next arrow action. nextInvocation is internally created using setCustomNextTarget: method. */ @property (strong, nonatomic) NSInvocation *nextInvocation; /** - @property nextInvocation - - @abstract customized Invocation to be called on done action. doneInvocation is internally created using setCustomDoneTarget: method. + Customized Invocation to be called on done action. doneInvocation is internally created using setCustomDoneTarget: method. */ @property (strong, nonatomic) NSInvocation *doneInvocation; +///------------ +/// @name Done +///------------ + /** - @method addDoneOnKeyboardWithTarget:action: - @method addDoneOnKeyboardWithTarget:action:titleText: - @method addDoneOnKeyboardWithTarget:action:shouldShowPlaceholder: - @method addRightButtonOnKeyboardWithText:target:action: - @method addRightButtonOnKeyboardWithText:target:action:titleText: - @method addRightButtonOnKeyboardWithText:target:action:shouldShowPlaceholder: + Helper function to add Done button on keyboard. - @abstract Helper functions to add Done button on keyboard. - - @param target: Target object for selector. Usually 'self'. - - @param action: Done button action name. Usually 'doneAction:(IQBarButtonItem*)item'. - - @param shouldShowPlaceholder: A boolean to indicate whether to show textField placeholder on IQToolbar'. - - @param titleText: text to show as title in IQToolbar'. + @param target Target object for selector. + @param action Done button action name. Usually 'doneAction:(IQBarButtonItem*)item'. */ - (void)addDoneOnKeyboardWithTarget:(id)target action:(SEL)action; -- (void)addDoneOnKeyboardWithTarget:(id)target action:(SEL)action titleText:(NSString*)titleText; -- (void)addDoneOnKeyboardWithTarget:(id)target action:(SEL)action shouldShowPlaceholder:(BOOL)showPlaceholder; -- (void)addRightButtonOnKeyboardWithText:(NSString*)text target:(id)target action:(SEL)action; -- (void)addRightButtonOnKeyboardWithText:(NSString*)text target:(id)target action:(SEL)action titleText:(NSString*)titleText; -- (void)addRightButtonOnKeyboardWithText:(NSString*)text target:(id)target action:(SEL)action shouldShowPlaceholder:(BOOL)showPlaceholder; /** - @method addCancelDoneOnKeyboardWithTarget:cancelAction:doneAction: - @method addCancelDoneOnKeyboardWithTarget:cancelAction:doneAction:titleText: - @method addCancelDoneOnKeyboardWithTarget:cancelAction:doneAction:shouldShowPlaceholder: - @method addLeftRightOnKeyboardWithTarget:leftButtonTitle:rightButtonTitle:leftButtonAction:rightButtonAction - @method addLeftRightOnKeyboardWithTarget:leftButtonTitle:rightButtonTitle:leftButtonAction:rightButtonAction:titleText: - @method addLeftRightOnKeyboardWithTarget:leftButtonTitle:rightButtonTitle:leftButtonAction:rightButtonAction:shouldShowPlaceholder: + Helper function to add Done button on keyboard. - @abstract Helper function to add Cancel and Done button on keyboard. + @param target Target object for selector. + @param action Done button action name. Usually 'doneAction:(IQBarButtonItem*)item'. + @param titleText text to show as title in IQToolbar'. + */ +- (void)addDoneOnKeyboardWithTarget:(id)target action:(SEL)action titleText:(NSString*)titleText; + +/** + Helper function to add Done button on keyboard. - @param target: Target object for selector. Usually 'self'. + @param target Target object for selector. + @param action Done button action name. Usually 'doneAction:(IQBarButtonItem*)item'. + @param shouldShowPlaceholder A boolean to indicate whether to show textField placeholder on IQToolbar'. + */ +- (void)addDoneOnKeyboardWithTarget:(id)target action:(SEL)action shouldShowPlaceholder:(BOOL)shouldShowPlaceholder; + +///------------ +/// @name Right +///------------ + +/** + Helper function to add Right button on keyboard. - @param cancelAction: Crevious button action name. Usually 'cancelAction:(IQBarButtonItem*)item'. + @param text Title for rightBarButtonItem, usually 'Done'. + @param target Target object for selector. + @param action Right button action name. Usually 'doneAction:(IQBarButtonItem*)item'. + */ +- (void)addRightButtonOnKeyboardWithText:(NSString*)text target:(id)target action:(SEL)action; + +/** + Helper function to add Right button on keyboard. - @param doneAction: Done button action name. Usually 'doneAction:(IQBarButtonItem*)item'. + @param text Title for rightBarButtonItem, usually 'Done'. + @param target Target object for selector. + @param action Right button action name. Usually 'doneAction:(IQBarButtonItem*)item'. + @param titleText text to show as title in IQToolbar'. + */ +- (void)addRightButtonOnKeyboardWithText:(NSString*)text target:(id)target action:(SEL)action titleText:(NSString*)titleText; + +/** + Helper function to add Right button on keyboard. - @param shouldShowPlaceholder: A boolean to indicate whether to show textField placeholder on IQToolbar'. + @param text Title for rightBarButtonItem, usually 'Done'. + @param target Target object for selector. + @param action Right button action name. Usually 'doneAction:(IQBarButtonItem*)item'. + @param shouldShowPlaceholder A boolean to indicate whether to show textField placeholder on IQToolbar'. + */ +- (void)addRightButtonOnKeyboardWithText:(NSString*)text target:(id)target action:(SEL)action shouldShowPlaceholder:(BOOL)shouldShowPlaceholder; + +///------------------ +/// @name Cancel/Done +///------------------ + +/** + Helper function to add Cancel and Done button on keyboard. - @param titleText: text to show as title in IQToolbar'. + @param target Target object for selector. + @param cancelAction Cancel button action name. Usually 'cancelAction:(IQBarButtonItem*)item'. + @param doneAction Done button action name. Usually 'doneAction:(IQBarButtonItem*)item'. */ - (void)addCancelDoneOnKeyboardWithTarget:(id)target cancelAction:(SEL)cancelAction doneAction:(SEL)doneAction; -- (void)addCancelDoneOnKeyboardWithTarget:(id)target cancelAction:(SEL)cancelAction doneAction:(SEL)doneAction titleText:(NSString*)titleText; -- (void)addCancelDoneOnKeyboardWithTarget:(id)target cancelAction:(SEL)cancelAction doneAction:(SEL)doneAction shouldShowPlaceholder:(BOOL)showPlaceholder; -- (void)addLeftRightOnKeyboardWithTarget:(id)target leftButtonTitle:(NSString*)leftTitle rightButtonTitle:(NSString*)rightTitle leftButtonAction:(SEL)leftAction rightButtonAction:(SEL)rightAction; -- (void)addLeftRightOnKeyboardWithTarget:(id)target leftButtonTitle:(NSString*)leftTitle rightButtonTitle:(NSString*)rightTitle leftButtonAction:(SEL)leftAction rightButtonAction:(SEL)rightAction titleText:(NSString*)titleText; -- (void)addLeftRightOnKeyboardWithTarget:(id)target leftButtonTitle:(NSString*)leftTitle rightButtonTitle:(NSString*)rightTitle leftButtonAction:(SEL)leftAction rightButtonAction:(SEL)rightAction shouldShowPlaceholder:(BOOL)showPlaceholder; /** - @method addPreviousNextDoneOnKeyboardWithTarget:previousAction:nextAction:doneAction - @method addPreviousNextDoneOnKeyboardWithTarget:previousAction:nextAction:doneAction:titleText: - @method addPreviousNextDoneOnKeyboardWithTarget:previousAction:nextAction:doneAction:shouldShowPlaceholder: - @method addPreviousNextRightOnKeyboardWithTarget:rightButtonTitle:previousAction:nextAction:rightButtonAction - @method addPreviousNextRightOnKeyboardWithTarget:rightButtonTitle:previousAction:nextAction:rightButtonAction:titleText: - @method addPreviousNextRightOnKeyboardWithTarget:rightButtonTitle:previousAction:nextAction:rightButtonAction:shouldShowPlaceholder: + Helper function to add Cancel and Done button on keyboard. - @abstract Helper function to add SegmentedNextPrevious and Done button on keyboard. + @param target Target object for selector. + @param cancelAction Cancel button action name. Usually 'cancelAction:(IQBarButtonItem*)item'. + @param doneAction Done button action name. Usually 'doneAction:(IQBarButtonItem*)item'. + @param titleText text to show as title in IQToolbar'. + */ +- (void)addCancelDoneOnKeyboardWithTarget:(id)target cancelAction:(SEL)cancelAction doneAction:(SEL)doneAction titleText:(NSString*)titleText; + +/** + Helper function to add Cancel and Done button on keyboard. - @param target: Target object for selector. Usually 'self'. + @param target Target object for selector. + @param cancelAction Cancel button action name. Usually 'cancelAction:(IQBarButtonItem*)item'. + @param doneAction Done button action name. Usually 'doneAction:(IQBarButtonItem*)item'. + @param shouldShowPlaceholder A boolean to indicate whether to show textField placeholder on IQToolbar'. + */ +- (void)addCancelDoneOnKeyboardWithTarget:(id)target cancelAction:(SEL)cancelAction doneAction:(SEL)doneAction shouldShowPlaceholder:(BOOL)shouldShowPlaceholder; + +///----------------- +/// @name Right/Left +///----------------- + +/** + Helper function to add Left and Right button on keyboard. - @param previousAction: Previous button action name. Usually 'previousAction:(IQSegmentedNextPrevious*)segmentedControl'. + @param target Target object for selector. + @param leftButtonTitle Title for leftBarButtonItem, usually 'Cancel'. + @param rightButtonTitle Title for rightBarButtonItem, usually 'Done'. + @param leftButtonAction Left button action name. Usually 'cancelAction:(IQBarButtonItem*)item'. + @param rightButtonAction Right button action name. Usually 'doneAction:(IQBarButtonItem*)item'. + */ +- (void)addLeftRightOnKeyboardWithTarget:(id)target leftButtonTitle:(NSString*)leftButtonTitle rightButtonTitle:(NSString*)rightButtonTitle leftButtonAction:(SEL)leftButtonAction rightButtonAction:(SEL)rightButtonAction; + +/** + Helper function to add Left and Right button on keyboard. - @param nextAction: Next button action name. Usually 'nextAction:(IQSegmentedNextPrevious*)segmentedControl'. + @param target Target object for selector. + @param leftButtonTitle Title for leftBarButtonItem, usually 'Cancel'. + @param rightButtonTitle Title for rightBarButtonItem, usually 'Done'. + @param leftButtonAction Left button action name. Usually 'cancelAction:(IQBarButtonItem*)item'. + @param rightButtonAction Right button action name. Usually 'doneAction:(IQBarButtonItem*)item'. + @param titleText text to show as title in IQToolbar'. + */ +- (void)addLeftRightOnKeyboardWithTarget:(id)target leftButtonTitle:(NSString*)leftButtonTitle rightButtonTitle:(NSString*)rightButtonTitle leftButtonAction:(SEL)leftButtonAction rightButtonAction:(SEL)rightButtonAction titleText:(NSString*)titleText; + +/** + Helper function to add Left and Right button on keyboard. - @param doneAction: Done button action name. Usually 'doneAction:(IQBarButtonItem*)item'. + @param target Target object for selector. + @param leftButtonTitle Title for leftBarButtonItem, usually 'Cancel'. + @param rightButtonTitle Title for rightBarButtonItem, usually 'Done'. + @param leftButtonAction Left button action name. Usually 'cancelAction:(IQBarButtonItem*)item'. + @param rightButtonAction Right button action name. Usually 'doneAction:(IQBarButtonItem*)item'. + @param shouldShowPlaceholder A boolean to indicate whether to show textField placeholder on IQToolbar'. + */ +- (void)addLeftRightOnKeyboardWithTarget:(id)target leftButtonTitle:(NSString*)leftButtonTitle rightButtonTitle:(NSString*)rightButtonTitle leftButtonAction:(SEL)leftButtonAction rightButtonAction:(SEL)rightButtonAction shouldShowPlaceholder:(BOOL)shouldShowPlaceholder; + +///------------------------- +/// @name Previous/Next/Done +///------------------------- + +/** + Helper function to add SegmentedNextPrevious/ArrowNextPrevious and Done button on keyboard. - @param shouldShowPlaceholder: A boolean to indicate whether to show textField placeholder on IQToolbar'. - - @param titleText: text to show as title in IQToolbar'. + @param target Target object for selector. + @param previousAction Previous button action name. Usually 'previousAction:(id)item'. + @param nextAction Next button action name. Usually 'nextAction:(id)item'. + @param doneAction Done button action name. Usually 'doneAction:(IQBarButtonItem*)item'. */ - (void)addPreviousNextDoneOnKeyboardWithTarget:(id)target previousAction:(SEL)previousAction nextAction:(SEL)nextAction doneAction:(SEL)doneAction; -- (void)addPreviousNextDoneOnKeyboardWithTarget:(id)target previousAction:(SEL)previousAction nextAction:(SEL)nextAction doneAction:(SEL)doneAction titleText:(NSString*)titleText; -- (void)addPreviousNextDoneOnKeyboardWithTarget:(id)target previousAction:(SEL)previousAction nextAction:(SEL)nextAction doneAction:(SEL)doneAction shouldShowPlaceholder:(BOOL)showPlaceholder; -- (void)addPreviousNextRightOnKeyboardWithTarget:(id)target rightButtonTitle:(NSString*)rightButtonTitle previousAction:(SEL)previousAction nextAction:(SEL)nextAction rightButtonAction:(SEL)rightButtonAction; -- (void)addPreviousNextRightOnKeyboardWithTarget:(id)target rightButtonTitle:(NSString*)rightButtonTitle previousAction:(SEL)previousAction nextAction:(SEL)nextAction rightButtonAction:(SEL)rightButtonAction titleText:(NSString*)titleText; -- (void)addPreviousNextRightOnKeyboardWithTarget:(id)target rightButtonTitle:(NSString*)rightButtonTitle previousAction:(SEL)previousAction nextAction:(SEL)nextAction rightButtonAction:(SEL)rightButtonAction shouldShowPlaceholder:(BOOL)showPlaceholder; /** - @method setEnablePrevious:next: + Helper function to add SegmentedNextPrevious/ArrowNextPrevious and Done button on keyboard. - @abstract Helper function to enable and disable previous next buttons. + @param target Target object for selector. + @param previousAction Previous button action name. Usually 'previousAction:(id)item'. + @param nextAction Next button action name. Usually 'nextAction:(id)item'. + @param doneAction Done button action name. Usually 'doneAction:(IQBarButtonItem*)item'. + @param titleText text to show as title in IQToolbar'. + */ +- (void)addPreviousNextDoneOnKeyboardWithTarget:(id)target previousAction:(SEL)previousAction nextAction:(SEL)nextAction doneAction:(SEL)doneAction titleText:(NSString*)titleText; + +/** + Helper function to add SegmentedNextPrevious/ArrowNextPrevious and Done button on keyboard. - @param isPreviousEnabled: BOOL to enable/disable previous button on keyboard. + @param target Target object for selector. + @param previousAction Previous button action name. Usually 'previousAction:(id)item'. + @param nextAction Next button action name. Usually 'nextAction:(id)item'. + @param doneAction Done button action name. Usually 'doneAction:(IQBarButtonItem*)item'. + @param shouldShowPlaceholder A boolean to indicate whether to show textField placeholder on IQToolbar'. + */ +- (void)addPreviousNextDoneOnKeyboardWithTarget:(id)target previousAction:(SEL)previousAction nextAction:(SEL)nextAction doneAction:(SEL)doneAction shouldShowPlaceholder:(BOOL)shouldShowPlaceholder; + +///-------------------------- +/// @name Previous/Next/Right +///-------------------------- + +/** + Helper function to add SegmentedNextPrevious/ArrowNextPrevious and Right button on keyboard. - @param isNextEnabled: BOOL to enable/disable next button on keyboard.. + @param target Target object for selector. + @param rightButtonTitle Title for rightBarButtonItem, usually 'Done'. + @param previousAction Previous button action name. Usually 'previousAction:(id)item'. + @param nextAction Next button action name. Usually 'nextAction:(id)item'. + @param rightButtonAction RightBarButton action name. Usually 'doneAction:(IQBarButtonItem*)item'. + */ +- (void)addPreviousNextRightOnKeyboardWithTarget:(id)target rightButtonTitle:(NSString*)rightButtonTitle previousAction:(SEL)previousAction nextAction:(SEL)nextAction rightButtonAction:(SEL)rightButtonAction; + +/** + Helper function to add SegmentedNextPrevious/ArrowNextPrevious and Right button on keyboard. + + @param target Target object for selector. + @param rightButtonTitle Title for rightBarButtonItem, usually 'Done'. + @param previousAction Previous button action name. Usually 'previousAction:(id)item'. + @param nextAction Next button action name. Usually 'nextAction:(id)item'. + @param rightButtonAction RightBarButton action name. Usually 'doneAction:(IQBarButtonItem*)item'. + @param titleText text to show as title in IQToolbar'. + */ +- (void)addPreviousNextRightOnKeyboardWithTarget:(id)target rightButtonTitle:(NSString*)rightButtonTitle previousAction:(SEL)previousAction nextAction:(SEL)nextAction rightButtonAction:(SEL)rightButtonAction titleText:(NSString*)titleText; + +/** + Helper function to add SegmentedNextPrevious/ArrowNextPrevious and Right button on keyboard. + + @param target Target object for selector. + @param rightButtonTitle Title for rightBarButtonItem, usually 'Done'. + @param previousAction Previous button action name. Usually 'previousAction:(id)item'. + @param nextAction Next button action name. Usually 'nextAction:(id)item'. + @param rightButtonAction RightBarButton action name. Usually 'doneAction:(IQBarButtonItem*)item'. + @param shouldShowPlaceholder A boolean to indicate whether to show textField placeholder on IQToolbar'. + */ +- (void)addPreviousNextRightOnKeyboardWithTarget:(id)target rightButtonTitle:(NSString*)rightButtonTitle previousAction:(SEL)previousAction nextAction:(SEL)nextAction rightButtonAction:(SEL)rightButtonAction shouldShowPlaceholder:(BOOL)shouldShowPlaceholder; + +///----------------------------------- +/// @name Enable/Disable Previous/Next +///----------------------------------- + +/** + Helper function to enable and disable previous next buttons. + + @param isPreviousEnabled BOOL to enable/disable previous button on keyboard. + @param isNextEnabled BOOL to enable/disable next button on keyboard.. */ - (void)setEnablePrevious:(BOOL)isPreviousEnabled next:(BOOL)isNextEnabled; diff --git a/KeyboardTextFieldDemo/.DS_Store b/KeyboardTextFieldDemo/.DS_Store index 474fa8368bf9ed30737992d543e49e3f0a5193aa..9e64480a44afab7d88d1590fe809ae34c8ec0b1c 100644 GIT binary patch delta 52 zcmZpvXsOr`Bgk~;!sIwXS7xv6-jhEF+VJJ(r?{k)mLxMUT!aXDF)o;VQAl}noX|2& E04?_vlK=n! delta 52 zcmZpvXsOr`BgmA%KRHg&mDy@t&EyY)Hhj7HDK06cCCLm77a>Akj0%%43Mp@n6I!MT E0QaL41^@s6 From b7592cbf71be460c76e20828debfca8e12409bb7 Mon Sep 17 00:00:00 2001 From: hackiftekhar Date: Wed, 8 Apr 2015 17:13:00 +0530 Subject: [PATCH 05/13] Ability to go next/previous programmatically #189 --- IQKeyBoardManager/IQKeyboardManager.h | 22 ++- IQKeyBoardManager/IQKeyboardManager.m | 205 ++++++++++++++++---------- KeyboardTextFieldDemo/.DS_Store | Bin 15364 -> 15364 bytes 3 files changed, 147 insertions(+), 80 deletions(-) diff --git a/IQKeyBoardManager/IQKeyboardManager.h b/IQKeyBoardManager/IQKeyboardManager.h index 7160fa1..b1ed50b 100755 --- a/IQKeyBoardManager/IQKeyboardManager.h +++ b/IQKeyBoardManager/IQKeyboardManager.h @@ -126,7 +126,7 @@ @property(nonatomic, assign) UIKeyboardAppearance keyboardAppearance; ///--------------------------------------------- -/// @name UITextField/UITextView Resign handling +/// @name UITextField/UITextView Next/Previous/Resign handling ///--------------------------------------------- /** @@ -139,6 +139,26 @@ */ - (void)resignFirstResponder; +/** + Returns YES if can navigate to previous responder textField/textView, otherwise NO. + */ +@property (nonatomic, readonly) BOOL canGoPrevious; + +/** + Returns YES if can navigate to next responder textField/textView, otherwise NO. + */ +@property (nonatomic, readonly) BOOL canGoNext; + +/** + Navigate to previous responder textField/textView. + */ +- (void)goPrevious; + +/** + Navigate to next responder textField/textView. + */ +- (void)goNext; + ///---------------------------- /// @name UIScrollView handling ///---------------------------- diff --git a/IQKeyBoardManager/IQKeyboardManager.m b/IQKeyBoardManager/IQKeyboardManager.m index 9a36d02..b7f4235 100755 --- a/IQKeyBoardManager/IQKeyboardManager.m +++ b/IQKeyBoardManager/IQKeyboardManager.m @@ -1194,7 +1194,7 @@ void _IQShowLog(NSString *logString); { // Retaining textFieldView UIView *textFieldRetain = _textFieldView; - + //Resigning first responder BOOL isResignFirstResponder = [_textFieldView resignFirstResponder]; @@ -1206,6 +1206,126 @@ void _IQShowLog(NSString *logString); _IQShowLog([NSString stringWithFormat:@"Refuses to Resign first responder: %@",[_textFieldView _IQDescription]]); } + else if (textFieldRetain.doneInvocation) + { + [textFieldRetain.doneInvocation invoke]; + } + } +} + +/** Returns YES if can navigate to previous responder textField/textView, otherwise NO. */ +-(BOOL)canGoPrevious +{ + //Getting all responder view's. + NSArray *textFields = [self responderViews]; + + if ([textFields containsObject:_textFieldView]) + { + //Getting index of current textField. + NSUInteger index = [textFields indexOfObject:_textFieldView]; + + //If it is not first textField. then it's previous object can becomeFirstResponder. + if (index > 0) + { + return YES; + } + } + + return NO; +} + +/** Returns YES if can navigate to next responder textField/textView, otherwise NO. */ +-(BOOL)canGoNext +{ + //Getting all responder view's. + NSArray *textFields = [self responderViews]; + + if ([textFields containsObject:_textFieldView]) + { + //Getting index of current textField. + NSUInteger index = [textFields indexOfObject:_textFieldView]; + + //If it is not last textField. then it's next object becomeFirstResponder. + if (index < textFields.count-1) + { + return YES; + } + } + + return NO; +} + +/** Navigate to previous responder textField/textView. */ +-(void)goPrevious +{ + //Getting all responder view's. + NSArray *textFields = [self responderViews]; + + if ([textFields containsObject:_textFieldView]) + { + //Getting index of current textField. + NSUInteger index = [textFields indexOfObject:_textFieldView]; + + //If it is not first textField. then it's previous object becomeFirstResponder. + if (index > 0) + { + UITextField *nextTextField = [textFields objectAtIndex:index-1]; + + // Retaining textFieldView + UIView *textFieldRetain = _textFieldView; + + BOOL isAcceptAsFirstResponder = [nextTextField becomeFirstResponder]; + + // If it refuses then becoming previous textFieldView as first responder again. (Bug ID: #96) + if (isAcceptAsFirstResponder == NO) + { + //If next field refuses to become first responder then restoring old textField as first responder. + [textFieldRetain becomeFirstResponder]; + + _IQShowLog([NSString stringWithFormat:@"Refuses to become first responder: %@",[nextTextField _IQDescription]]); + } + else if (textFieldRetain.previousInvocation) + { + [textFieldRetain.previousInvocation invoke]; + } + } + } +} + +/** Navigate to next responder textField/textView. */ +-(void)goNext +{ + //Getting all responder view's. + NSArray *textFields = [self responderViews]; + + if ([textFields containsObject:_textFieldView]) + { + //Getting index of current textField. + NSUInteger index = [textFields indexOfObject:_textFieldView]; + + //If it is not last textField. then it's next object becomeFirstResponder. + if (index < textFields.count-1) + { + UITextField *nextTextField = [textFields objectAtIndex:index+1]; + + // Retaining textFieldView + UIView *textFieldRetain = _textFieldView; + + BOOL isAcceptAsFirstResponder = [nextTextField becomeFirstResponder]; + + // If it refuses then becoming previous textFieldView as first responder again. (Bug ID: #96) + if (isAcceptAsFirstResponder == NO) + { + //If next field refuses to become first responder then restoring old textField as first responder. + [textFieldRetain becomeFirstResponder]; + + _IQShowLog([NSString stringWithFormat:@"Refuses to become first responder: %@",[nextTextField _IQDescription]]); + } + else if (textFieldRetain.nextInvocation) + { + [textFieldRetain.nextInvocation invoke]; + } + } } } @@ -1436,37 +1556,9 @@ void _IQShowLog(NSString *logString); [[UIDevice currentDevice] playInputClick]; } - //Getting all responder view's. - NSArray *textFields = [self responderViews]; - - if ([textFields containsObject:_textFieldView]) + if ([self canGoPrevious]) { - //Getting index of current textField. - NSUInteger index = [textFields indexOfObject:_textFieldView]; - - //If it is not first textField. then it's previous object becomeFirstResponder. - if (index > 0) - { - UITextField *nextTextField = [textFields objectAtIndex:index-1]; - - // Retaining textFieldView - UIView *textFieldRetain = _textFieldView; - - BOOL isAcceptAsFirstResponder = [nextTextField becomeFirstResponder]; - - // If it refuses then becoming previous textFieldView as first responder again. (Bug ID: #96) - if (isAcceptAsFirstResponder == NO) - { - //If next field refuses to become first responder then restoring old textField as first responder. - [textFieldRetain becomeFirstResponder]; - - _IQShowLog([NSString stringWithFormat:@"Refuses to become first responder: %@",[nextTextField _IQDescription]]); - } - else if (textFieldRetain.previousInvocation) - { - [textFieldRetain.previousInvocation invoke]; - } - } + [self goPrevious]; } } @@ -1480,37 +1572,9 @@ void _IQShowLog(NSString *logString); [[UIDevice currentDevice] playInputClick]; } - //Getting all responder view's. - NSArray *textFields = [self responderViews]; - - if ([textFields containsObject:_textFieldView]) + if ([self canGoNext]) { - //Getting index of current textField. - NSUInteger index = [textFields indexOfObject:_textFieldView]; - - //If it is not last textField. then it's next object becomeFirstResponder. - if (index < textFields.count-1) - { - UITextField *nextTextField = [textFields objectAtIndex:index+1]; - - // Retaining textFieldView - UIView *textFieldRetain = _textFieldView; - - BOOL isAcceptAsFirstResponder = [nextTextField becomeFirstResponder]; - - // If it refuses then becoming previous textFieldView as first responder again. (Bug ID: #96) - if (isAcceptAsFirstResponder == NO) - { - //If next field refuses to become first responder then restoring old textField as first responder. - [textFieldRetain becomeFirstResponder]; - - _IQShowLog([NSString stringWithFormat:@"Refuses to become first responder: %@",[nextTextField _IQDescription]]); - } - else if (textFieldRetain.nextInvocation) - { - [textFieldRetain.nextInvocation invoke]; - } - } + [self goNext]; } } @@ -1524,24 +1588,7 @@ void _IQShowLog(NSString *logString); [[UIDevice currentDevice] playInputClick]; } - // Retaining textFieldView - UIView *textFieldRetain = _textFieldView; - - //Resigning first responder - BOOL isResignFirstResponder = [_textFieldView resignFirstResponder]; - - // If it refuses then becoming it as first responder again. (Bug ID: #96) - if (isResignFirstResponder == NO) - { - //If it refuses to resign then becoming it first responder again for getting notifications callback. - [textFieldRetain becomeFirstResponder]; - - _IQShowLog([NSString stringWithFormat:@"Refuses to Resign first responder: %@",[_textFieldView _IQDescription]]); - } - else if (textFieldRetain.doneInvocation) - { - [textFieldRetain.doneInvocation invoke]; - } + [self resignFirstResponder]; } #pragma mark - Tracking untracking diff --git a/KeyboardTextFieldDemo/.DS_Store b/KeyboardTextFieldDemo/.DS_Store index 9e64480a44afab7d88d1590fe809ae34c8ec0b1c..6141ef1ff5cf19ded51dca811ad8e3c5522afb6f 100644 GIT binary patch delta 15 WcmZpvXsOr`Bgk~WYjd37GA#f$bp~?) delta 15 WcmZpvXsOr`Bgk~;!sa-^Wm*6@1O~PM From d16d1864e93256088411decd8e1f6a3fb4e9c653 Mon Sep 17 00:00:00 2001 From: hackiftekhar Date: Wed, 8 Apr 2015 18:10:35 +0530 Subject: [PATCH 06/13] Fixed textField font for iOS 6. #188 --- .../IQToolbar/IQTitleBarButtonItem.m | 22 ++++++++++++++--- .../IQToolbar/IQUIView+IQKeyboardToolbar.m | 24 +++++++++---------- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/IQKeyBoardManager/IQToolbar/IQTitleBarButtonItem.m b/IQKeyBoardManager/IQToolbar/IQTitleBarButtonItem.m index f116a04..3c872d1 100644 --- a/IQKeyBoardManager/IQToolbar/IQTitleBarButtonItem.m +++ b/IQKeyBoardManager/IQToolbar/IQTitleBarButtonItem.m @@ -23,6 +23,7 @@ #import "IQTitleBarButtonItem.h" #import "IQKeyboardManagerConstants.h" +#import "IQKeyboardManagerConstantsInternal.h" #import #ifndef NSFoundationVersionNumber_iOS_5_1 @@ -31,6 +32,7 @@ @implementation IQTitleBarButtonItem { + UIView *_titleView; UILabel *_titleLabel; } @synthesize font = _font; @@ -40,15 +42,29 @@ self = [super initWithTitle:nil style:UIBarButtonItemStylePlain target:nil action:nil]; if (self) { - _titleLabel = [[UILabel alloc] initWithFrame:frame]; + _titleView = [[UIView alloc] initWithFrame:frame]; + _titleView.backgroundColor = [UIColor clearColor]; + _titleView.autoresizingMask = UIViewAutoresizingFlexibleWidth; + + _titleLabel = [[UILabel alloc] initWithFrame:_titleView.bounds]; + + if (IQ_IS_IOS7_OR_GREATER) + { + [_titleLabel setTextColor:[UIColor lightGrayColor]]; + } + else + { + [_titleLabel setTextColor:[UIColor whiteColor]]; + } + [_titleLabel setBackgroundColor:[UIColor clearColor]]; [_titleLabel setTextAlignment:NSTextAlignmentCenter]; [_titleLabel setAutoresizingMask:UIViewAutoresizingFlexibleWidth]; [self setTitle:title]; [self setFont:[UIFont boldSystemFontOfSize:12.0]]; - self.title = title; + [_titleView addSubview:_titleLabel]; - self.customView = _titleLabel; + self.customView = _titleView; self.enabled = NO; } return self; diff --git a/IQKeyBoardManager/IQToolbar/IQUIView+IQKeyboardToolbar.m b/IQKeyBoardManager/IQToolbar/IQUIView+IQKeyboardToolbar.m index 582a521..024112f 100644 --- a/IQKeyBoardManager/IQToolbar/IQUIView+IQKeyboardToolbar.m +++ b/IQKeyBoardManager/IQToolbar/IQUIView+IQKeyboardToolbar.m @@ -108,6 +108,8 @@ } +#pragma mark - Toolbar on UIKeyboard + - (void)addRightButtonOnKeyboardWithText:(NSString*)text target:(id)target action:(SEL)action titleText:(NSString*)titleText { // If can't set InputAccessoryView. Then return @@ -141,10 +143,10 @@ else { /* - 57 done button frame. - 8 distance maintenance + 64 done button frame. + 16 distance maintenance */ - buttonFrame = CGRectMake(0, 0, toolbar.frame.size.width-57.0-8, 44); + buttonFrame = CGRectMake(0, 0, toolbar.frame.size.width-64.0-16, 44); } IQTitleBarButtonItem *title = [[IQTitleBarButtonItem alloc] initWithFrame:buttonFrame title:titleText]; @@ -214,10 +216,10 @@ else { /* - 57 done button frame. - 8 distance maintenance + 64 done button frame. + 16 distance maintenance */ - buttonFrame = CGRectMake(0, 0, toolbar.frame.size.width-57.0-8, 44); + buttonFrame = CGRectMake(0, 0, toolbar.frame.size.width-64.0-16, 44); } IQTitleBarButtonItem *title = [[IQTitleBarButtonItem alloc] initWithFrame:buttonFrame title:titleText]; @@ -239,8 +241,6 @@ [(UITextField*)self setInputAccessoryView:toolbar]; } - -#pragma mark - Toolbar on UIKeyboard -(void)addDoneOnKeyboardWithTarget:(id)target action:(SEL)action shouldShowPlaceholder:(BOOL)showPlaceholder { NSString *title; @@ -501,10 +501,10 @@ { /* 135 next/previous maximum x. - 57 done button frame. + 64 done button frame. 8+8 distance maintenance */ - buttonFrame = CGRectMake(0, 0, toolbar.frame.size.width-135-57.0-16, 44); + buttonFrame = CGRectMake(0, 0, toolbar.frame.size.width-135-64.0-16, 44); } IQTitleBarButtonItem *title = [[IQTitleBarButtonItem alloc] initWithFrame:buttonFrame title:titleText]; @@ -627,10 +627,10 @@ { /* 135 next/previous maximum x. - 57 done button frame. + 64 done button frame. 8+8 distance maintenance */ - buttonFrame = CGRectMake(0, 0, toolbar.frame.size.width-135-57.0-16, 44); + buttonFrame = CGRectMake(0, 0, toolbar.frame.size.width-135-64.0-16, 44); } IQTitleBarButtonItem *title = [[IQTitleBarButtonItem alloc] initWithFrame:buttonFrame title:titleText]; From b3642761a93f8e363ac05ad4234d5bf302dceba7 Mon Sep 17 00:00:00 2001 From: hackiftekhar Date: Mon, 20 Apr 2015 16:03:56 +0530 Subject: [PATCH 07/13] Fixed #198, Fixed #197 --- IQKeyBoardManager/IQKeyboardManager.m | 35 ++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/IQKeyBoardManager/IQKeyboardManager.m b/IQKeyBoardManager/IQKeyboardManager.m index b7f4235..1104df8 100755 --- a/IQKeyBoardManager/IQKeyboardManager.m +++ b/IQKeyBoardManager/IQKeyboardManager.m @@ -130,7 +130,12 @@ void _IQShowLog(NSString *logString); UITapGestureRecognizer *_tapGesture; /*******************************************/ + + /** Default toolbar tintColor to be used within the project. Default is black. */ + UIColor *_defaultToolbarTintColor; + /*******************************************/ + /** Set of restricted classes for library */ NSMutableSet *_disabledClasses; @@ -234,6 +239,7 @@ void _IQShowLog(NSString *logString); //Setting it's initial values _enable = NO; + _defaultToolbarTintColor = [UIColor blackColor]; [self setCanAdjustTextView:NO]; [self setShouldPlayInputClicks:NO]; [self setShouldResignOnTouchOutside:NO]; @@ -941,6 +947,25 @@ void _IQShowLog(NSString *logString); _IQShowLog([NSString stringWithFormat:@"Restoring %@ contentInset to : %@ and contentOffset to : %@",[_lastScrollView _IQDescription],NSStringFromUIEdgeInsets(_startingContentInsets),NSStringFromCGPoint(_startingContentOffset)]); + // TODO: restore scrollView state + // This is temporary solution. Have to implement the save and restore scrollView state + UIScrollView *superscrollView = _lastScrollView; + while ((superscrollView = (UIScrollView*)[superscrollView superviewOfClassType:[UIScrollView class]])) + { + MAX(superscrollView.contentSize.height, CGRectGetHeight(superscrollView.frame)); + + CGSize contentSize = CGSizeMake(MAX(superscrollView.contentSize.width, CGRectGetWidth(superscrollView.frame)), MAX(superscrollView.contentSize.height, CGRectGetHeight(superscrollView.frame))); + + CGFloat minimumY = contentSize.height-CGRectGetHeight(superscrollView.frame); + + if (minimumY Date: Mon, 20 Apr 2015 16:31:33 +0530 Subject: [PATCH 08/13] Added 'setNeedsLayout' and 'layoutIfNeeded' to animate the content #160 --- IQKeyBoardManager/IQKeyboardManager.m | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/IQKeyBoardManager/IQKeyboardManager.m b/IQKeyBoardManager/IQKeyboardManager.m index 1104df8..38a016f 100755 --- a/IQKeyBoardManager/IQKeyboardManager.m +++ b/IQKeyBoardManager/IQKeyboardManager.m @@ -422,6 +422,11 @@ void _IQShowLog(NSString *logString); [UIView animateWithDuration:_animationDuration delay:0 options:(_animationCurve|UIViewAnimationOptionBeginFromCurrentState) animations:^{ // Setting it's new frame [controller.view setFrame:frame]; + + //Animating content (Bug ID: #160) + [controller.view setNeedsLayout]; + [controller.view layoutIfNeeded]; + _IQShowLog([NSString stringWithFormat:@"Set %@ frame to : %@",[controller _IQDescription],NSStringFromCGRect(frame)]); } completion:NULL]; } @@ -984,6 +989,11 @@ void _IQShowLog(NSString *logString); _IQShowLog([NSString stringWithFormat:@"Restoring %@ frame to : %@",[_rootViewController _IQDescription],NSStringFromCGRect(_topViewBeginRect)]); // Setting it's new frame [_rootViewController.view setFrame:_topViewBeginRect]; + + //Animating content (Bug ID: #160) + [_rootViewController.view setNeedsLayout]; + [_rootViewController.view layoutIfNeeded]; + } completion:NULL]; _rootViewController = nil; } From 459bb334059cf28fef255196971eb64c56fe5c20 Mon Sep 17 00:00:00 2001 From: hackiftekhar Date: Mon, 20 Apr 2015 17:16:28 +0530 Subject: [PATCH 09/13] Suppress deprecation warnings --- .../IQSegmentedNextPrevious/IQSegmentedNextPrevious.m | 3 +++ 1 file changed, 3 insertions(+) diff --git a/IQKeyBoardManager/IQSegmentedNextPrevious/IQSegmentedNextPrevious.m b/IQKeyBoardManager/IQSegmentedNextPrevious/IQSegmentedNextPrevious.m index b083b1f..2b293d3 100644 --- a/IQKeyBoardManager/IQSegmentedNextPrevious/IQSegmentedNextPrevious.m +++ b/IQKeyBoardManager/IQSegmentedNextPrevious/IQSegmentedNextPrevious.m @@ -50,7 +50,10 @@ { if (IQ_IS_IOS7_OR_GREATER == NO) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" [self setSegmentedControlStyle:UISegmentedControlStyleBar]; +#pragma GCC diagnostic pop } [self setMomentary:YES]; From 1c8538f0359f3ac718f2b9293a6f6fd1cc934874 Mon Sep 17 00:00:00 2001 From: hackiftekhar Date: Sat, 18 Apr 2015 21:42:18 +0530 Subject: [PATCH 10/13] Working on NavigationBar hidden issue #187 --- IQKeyBoardManager/IQKeyboardManager.m | 82 +++++++++++++++---- .../Base.lproj/Main.storyboard | 8 +- 2 files changed, 72 insertions(+), 18 deletions(-) diff --git a/IQKeyBoardManager/IQKeyboardManager.m b/IQKeyBoardManager/IQKeyboardManager.m index 38a016f..bb03ef0 100755 --- a/IQKeyBoardManager/IQKeyboardManager.m +++ b/IQKeyBoardManager/IQKeyboardManager.m @@ -35,11 +35,13 @@ #import #import #import +#import #import #import #ifdef NSFoundationVersionNumber_iOS_5_1 #import +#import #endif NSInteger const kIQDoneButtonToolbarTag = -1002; @@ -460,8 +462,24 @@ void _IQShowLog(NSString *logString); // Getting RootViewRect. CGRect rootViewRect = [[rootController view] frame]; //Getting statusBarFrame + CGFloat topLayoutGuide = 0; + CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame]; + switch (interfaceOrientation) + { + case UIInterfaceOrientationLandscapeLeft: + case UIInterfaceOrientationLandscapeRight: + topLayoutGuide = CGRectGetWidth(statusBarFrame); + break; + case UIInterfaceOrientationPortrait: + case UIInterfaceOrientationPortraitUpsideDown: + topLayoutGuide = CGRectGetHeight(statusBarFrame); + break; + default: + break; + } + CGFloat move = 0; // Move positive = textField is hidden. // Move negative = textField is showing. @@ -470,16 +488,16 @@ void _IQShowLog(NSString *logString); switch (interfaceOrientation) { case UIInterfaceOrientationLandscapeLeft: - move = MIN(CGRectGetMinX(textFieldViewRect)-(CGRectGetWidth(statusBarFrame)+5), CGRectGetMaxX(textFieldViewRect)-(CGRectGetWidth(keyWindow.frame)-_kbSize.width)); + move = MIN(CGRectGetMinX(textFieldViewRect)-(topLayoutGuide+5), CGRectGetMaxX(textFieldViewRect)-(CGRectGetWidth(keyWindow.frame)-_kbSize.width)); break; case UIInterfaceOrientationLandscapeRight: - move = MIN(CGRectGetWidth(keyWindow.frame)-CGRectGetMaxX(textFieldViewRect)-(CGRectGetWidth(statusBarFrame)+5), _kbSize.width-CGRectGetMinX(textFieldViewRect)); + move = MIN(CGRectGetWidth(keyWindow.frame)-CGRectGetMaxX(textFieldViewRect)-(topLayoutGuide+5), _kbSize.width-CGRectGetMinX(textFieldViewRect)); break; case UIInterfaceOrientationPortrait: - move = MIN(CGRectGetMinY(textFieldViewRect)-(CGRectGetHeight(statusBarFrame)+5), CGRectGetMaxY(textFieldViewRect)-(CGRectGetHeight(keyWindow.frame)-_kbSize.height)); + move = MIN(CGRectGetMinY(textFieldViewRect)-(topLayoutGuide+5), CGRectGetMaxY(textFieldViewRect)-(CGRectGetHeight(keyWindow.frame)-_kbSize.height)); break; case UIInterfaceOrientationPortraitUpsideDown: - move = MIN(CGRectGetHeight(keyWindow.frame)-CGRectGetMaxY(textFieldViewRect)-(CGRectGetHeight(statusBarFrame)+5), _kbSize.height-CGRectGetMinY(textFieldViewRect)); + move = MIN(CGRectGetHeight(keyWindow.frame)-CGRectGetMaxY(textFieldViewRect)-(topLayoutGuide+5), _kbSize.height-CGRectGetMinY(textFieldViewRect)); break; default: break; @@ -564,8 +582,42 @@ void _IQShowLog(NSString *logString); //Rearranging the expected Y offset according to the view. shouldOffsetY = MIN(shouldOffsetY, lastViewRect.origin.y/*-5*/); //-5 is for good UI.//Commenting -5 (Bug ID: #69) - //Subtracting the Y offset from the move variable, because we are going to change scrollView's contentOffset.y to shouldOffsetY. - move -= (shouldOffsetY-superScrollView.contentOffset.y); + //We're working on NavigationBar hidden issue +// //[superScrollView superviewOfClassType:[UIScrollView class]] == nil If processing scrollView is last scrollView in upper hierarchy (there is no other scrollView upper hierrchy.) +// //[_textFieldView isKindOfClass:[UITextView class]] If is a UITextView type +// //shouldOffsetY > 0 shouldOffsetY must be greater than in order to keep distance from navigationBar (Bug ID: #92) +// if ([_textFieldView isKindOfClass:[UITextView class]] && [superScrollView superviewOfClassType:[UIScrollView class]] == nil && shouldOffsetY > 0) +// { +// CGFloat maintainTopLayout = 0; +// +// if ([_textFieldView.viewController respondsToSelector:@selector(topLayoutGuide)]) +// { +// maintainTopLayout = [_textFieldView.viewController.topLayoutGuide length]; +// } +// else +// { +// maintainTopLayout = _textFieldView.viewController.navigationController.navigationBar.frame.size.height; +// } +// +// maintainTopLayout+= 20; //For good UI +// +// // Converting Rectangle according to window bounds. +// CGRect expectedTextFieldViewRect = [[_textFieldView superview] convertRect:_textFieldView.frame toView:keyWindow]; +// expectedTextFieldViewRect.origin.y -= shouldOffsetY; +// +// if (expectedTextFieldViewRect.origin.y < maintainTopLayout) +// { +// shouldOffsetY -= maintainTopLayout - expectedTextFieldViewRect.origin.y; // removing -5 from current shouldOffsetY in order to make distance from NavigationBar +// } +// +// move = 0; +// } +// else + { + //Subtracting the Y offset from the move variable, because we are going to change scrollView's contentOffset.y to shouldOffsetY. + move -= (shouldOffsetY-superScrollView.contentOffset.y); + } + //Getting problem while using `setContentOffset:animated:`, So I used animation API. [UIView animateWithDuration:_animationDuration delay:0 options:(_animationCurve|UIViewAnimationOptionBeginFromCurrentState) animations:^{ @@ -631,10 +683,12 @@ void _IQShowLog(NSString *logString); //Going ahead. No else if. } - //Special case for UITextView(Readjusting the move variable when textView hight is too big to fit on screen). - //If we have permission to adjust the textView, then let's do it on behalf of user. (Enhancement ID: #15) - //Added _isTextFieldViewFrameChanged. (Bug ID: #92) - if (_canAdjustTextView && [_textFieldView isKindOfClass:[UITextView class]] && _keyboardManagerFlags.isTextFieldViewFrameChanged == NO) + //Special case for UITextView(Readjusting the move variable when textView hight is too big to fit on screen) + //_canAdjustTextView If we have permission to adjust the textView, then let's do it on behalf of user (Enhancement ID: #15) + //_lastScrollView If not having inside any scrollView, (now contentInset manages the full screen textView. + //[_textFieldView isKindOfClass:[UITextView class]] If is a UITextView type + //_isTextFieldViewFrameChanged If frame is not change by library in past (Bug ID: #92) + if (_canAdjustTextView && (_lastScrollView == NO) && [_textFieldView isKindOfClass:[UITextView class]] && _keyboardManagerFlags.isTextFieldViewFrameChanged == NO) { CGFloat textViewHeight = CGRectGetHeight(_textFieldView.frame); @@ -642,11 +696,11 @@ void _IQShowLog(NSString *logString); { case UIInterfaceOrientationLandscapeLeft: case UIInterfaceOrientationLandscapeRight: - textViewHeight = MIN(textViewHeight, (CGRectGetWidth(keyWindow.frame)-_kbSize.width-(CGRectGetWidth(statusBarFrame)+5))); + textViewHeight = MIN(textViewHeight, (CGRectGetWidth(keyWindow.frame)-_kbSize.width-(topLayoutGuide+5))); break; case UIInterfaceOrientationPortrait: case UIInterfaceOrientationPortraitUpsideDown: - textViewHeight = MIN(textViewHeight, (CGRectGetHeight(keyWindow.frame)-_kbSize.height-(CGRectGetHeight(statusBarFrame)+5))); + textViewHeight = MIN(textViewHeight, (CGRectGetHeight(keyWindow.frame)-_kbSize.height-(topLayoutGuide+5))); break; default: break; @@ -687,10 +741,10 @@ void _IQShowLog(NSString *logString); { case UIInterfaceOrientationLandscapeLeft: case UIInterfaceOrientationLandscapeRight: - minimumY = CGRectGetWidth(keyWindow.frame)-rootViewRect.size.height-statusBarFrame.size.width-(_kbSize.width-_keyboardDistanceFromTextField); break; + minimumY = CGRectGetWidth(keyWindow.frame)-rootViewRect.size.height-topLayoutGuide-(_kbSize.width-_keyboardDistanceFromTextField); break; case UIInterfaceOrientationPortrait: case UIInterfaceOrientationPortraitUpsideDown: - minimumY = (CGRectGetHeight(keyWindow.frame)-rootViewRect.size.height-statusBarFrame.size.height)/2-(_kbSize.height-_keyboardDistanceFromTextField); break; + minimumY = (CGRectGetHeight(keyWindow.frame)-rootViewRect.size.height-topLayoutGuide)/2-(_kbSize.height-_keyboardDistanceFromTextField); break; default: break; } diff --git a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/Base.lproj/Main.storyboard b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/Base.lproj/Main.storyboard index c1dc88c..5e6cdcc 100644 --- a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/Base.lproj/Main.storyboard +++ b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/Base.lproj/Main.storyboard @@ -1,5 +1,5 @@ - + @@ -1549,7 +1549,7 @@ textField.inputAcessoryView = [[UIView alloc] init]; - + @@ -1588,7 +1588,7 @@ textField.inputAcessoryView = [[UIView alloc] init]; - + @@ -1760,7 +1760,7 @@ textField.inputAcessoryView = [[UIView alloc] init]; - + From 6f7c8f4b29408e4c123720a807ba4cb6aaa2c3ea Mon Sep 17 00:00:00 2001 From: hackiftekhar Date: Sat, 18 Apr 2015 21:43:46 +0530 Subject: [PATCH 11/13] Working on NavigationBar hidden issue #187 --- .../KeyboardTextFieldDemo/Base.lproj/Main.storyboard | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/Base.lproj/Main.storyboard b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/Base.lproj/Main.storyboard index 5e6cdcc..5886fcf 100644 --- a/KeyboardTextFieldDemo/KeyboardTextFieldDemo/Base.lproj/Main.storyboard +++ b/KeyboardTextFieldDemo/KeyboardTextFieldDemo/Base.lproj/Main.storyboard @@ -1760,7 +1760,7 @@ textField.inputAcessoryView = [[UIView alloc] init]; - + From 3caf75f8c09c2de41cb7b49add465ba9ced1a04a Mon Sep 17 00:00:00 2001 From: hackiftekhar Date: Sun, 19 Apr 2015 16:30:26 +0530 Subject: [PATCH 12/13] Fixed an issue with UIScrollView support --- IQKeyBoardManager/IQKeyboardManager.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IQKeyBoardManager/IQKeyboardManager.m b/IQKeyBoardManager/IQKeyboardManager.m index bb03ef0..d95672f 100755 --- a/IQKeyBoardManager/IQKeyboardManager.m +++ b/IQKeyBoardManager/IQKeyboardManager.m @@ -571,7 +571,7 @@ void _IQShowLog(NSString *logString); UIScrollView *superScrollView = _lastScrollView; //Looping in upper hierarchy until we don't found any scrollView in it's upper hirarchy till UIWindow object. - while (superScrollView && (move>0?(move > (-superScrollView.contentOffset.y)):superScrollView.contentOffset.y>0) ) + while (superScrollView && (move>0?(move > (-superScrollView.contentOffset.y-superScrollView.contentInset.top)):superScrollView.contentOffset.y>0) ) { //Getting lastViewRect. CGRect lastViewRect = [[lastView superview] convertRect:lastView.frame toView:superScrollView]; From f5c107fd638d52c98f2e8202e6de85f601d9139c Mon Sep 17 00:00:00 2001 From: hackiftekhar Date: Sun, 19 Apr 2015 20:52:38 +0530 Subject: [PATCH 13/13] Fixed #187, Fixed #161, --- IQKeyBoardManager/IQKeyboardManager.m | 70 ++++++++++++++++----------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/IQKeyBoardManager/IQKeyboardManager.m b/IQKeyBoardManager/IQKeyboardManager.m index d95672f..4b29ae2 100755 --- a/IQKeyBoardManager/IQKeyboardManager.m +++ b/IQKeyBoardManager/IQKeyboardManager.m @@ -582,37 +582,51 @@ void _IQShowLog(NSString *logString); //Rearranging the expected Y offset according to the view. shouldOffsetY = MIN(shouldOffsetY, lastViewRect.origin.y/*-5*/); //-5 is for good UI.//Commenting -5 (Bug ID: #69) - //We're working on NavigationBar hidden issue -// //[superScrollView superviewOfClassType:[UIScrollView class]] == nil If processing scrollView is last scrollView in upper hierarchy (there is no other scrollView upper hierrchy.) -// //[_textFieldView isKindOfClass:[UITextView class]] If is a UITextView type -// //shouldOffsetY > 0 shouldOffsetY must be greater than in order to keep distance from navigationBar (Bug ID: #92) -// if ([_textFieldView isKindOfClass:[UITextView class]] && [superScrollView superviewOfClassType:[UIScrollView class]] == nil && shouldOffsetY > 0) -// { -// CGFloat maintainTopLayout = 0; -// + //[superScrollView superviewOfClassType:[UIScrollView class]] == nil If processing scrollView is last scrollView in upper hierarchy (there is no other scrollView upper hierrchy.) + //[_textFieldView isKindOfClass:[UITextView class]] If is a UITextView type + //shouldOffsetY > 0 shouldOffsetY must be greater than in order to keep distance from navigationBar (Bug ID: #92) + if ([_textFieldView isKindOfClass:[UITextView class]] && [superScrollView superviewOfClassType:[UIScrollView class]] == nil && shouldOffsetY > 0) + { + CGFloat maintainTopLayout = 0; + + //When uncommenting this, each calculation goes to well, but don't know why scrollView doesn't adjusting it's contentOffset at bottom // if ([_textFieldView.viewController respondsToSelector:@selector(topLayoutGuide)]) -// { // maintainTopLayout = [_textFieldView.viewController.topLayoutGuide length]; -// } // else -// { -// maintainTopLayout = _textFieldView.viewController.navigationController.navigationBar.frame.size.height; -// } -// -// maintainTopLayout+= 20; //For good UI -// -// // Converting Rectangle according to window bounds. -// CGRect expectedTextFieldViewRect = [[_textFieldView superview] convertRect:_textFieldView.frame toView:keyWindow]; -// expectedTextFieldViewRect.origin.y -= shouldOffsetY; -// -// if (expectedTextFieldViewRect.origin.y < maintainTopLayout) -// { -// shouldOffsetY -= maintainTopLayout - expectedTextFieldViewRect.origin.y; // removing -5 from current shouldOffsetY in order to make distance from NavigationBar -// } -// -// move = 0; -// } -// else + maintainTopLayout = CGRectGetMaxY(_textFieldView.viewController.navigationController.navigationBar.frame); + + maintainTopLayout+= 10; //For good UI + + // Converting Rectangle according to window bounds. + CGRect currentTextFieldViewRect = [[_textFieldView superview] convertRect:_textFieldView.frame toView:keyWindow]; + CGFloat expectedFixDistance = shouldOffsetY; + + //Calculating expected fix distance which needs to be managed from navigation bar + switch (interfaceOrientation) + { + case UIInterfaceOrientationLandscapeLeft: + expectedFixDistance = CGRectGetMinX(currentTextFieldViewRect) - maintainTopLayout; + break; + case UIInterfaceOrientationLandscapeRight: + expectedFixDistance = (CGRectGetWidth(keyWindow.frame)-CGRectGetMaxX(currentTextFieldViewRect)) - maintainTopLayout; + break; + case UIInterfaceOrientationPortrait: + expectedFixDistance = CGRectGetMinY(currentTextFieldViewRect) - maintainTopLayout; + break; + case UIInterfaceOrientationPortraitUpsideDown: + expectedFixDistance = (CGRectGetHeight(keyWindow.frame)-CGRectGetMaxY(currentTextFieldViewRect)) - maintainTopLayout; + break; + default: + break; + } + + //Now if expectedOffsetY (superScrollView.contentOffset.y + expectedFixDistance) is lower than current shouldOffsetY, which means we're in a position where navigationBar up and hide, then reducing shouldOffsetY with expectedOffsetY (superScrollView.contentOffset.y + expectedFixDistance) + shouldOffsetY = MIN(shouldOffsetY, superScrollView.contentOffset.y + expectedFixDistance); + + //Setting move to 0 because now we don't want to move any view anymore (All will be managed by our contentInset logic. + move = 0; + } + else { //Subtracting the Y offset from the move variable, because we are going to change scrollView's contentOffset.y to shouldOffsetY. move -= (shouldOffsetY-superScrollView.contentOffset.y);