新版本

This commit is contained in:
roy
2019-03-12 09:26:46 +08:00
parent cbbfcb098a
commit c08d198e11
431 changed files with 19432 additions and 9136 deletions
@@ -0,0 +1,51 @@
//
// IQBarButtonItem.h
// https://github.com/hackiftekhar/IQKeyboardManager
// Copyright (c) 2013-16 Iftekhar Qurashi.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <UIKit/UIBarButtonItem.h>
@class NSInvocation;
/**
IQBarButtonItem used for IQToolbar.
*/
@interface IQBarButtonItem : UIBarButtonItem
/**
Boolean to know if it's a system item or custom item
*/
@property (nonatomic, readonly) BOOL isSystemItem;
/**
Additional target & action to do get callback action. Note that setting custom target & selector doesn't affect native functionality, this is just an additional target to get a callback.
@param target Target object.
@param action Target Selector.
*/
-(void)setTarget:(nullable id)target action:(nullable SEL)action;
/**
Customized Invocation to be called when button is pressed. invocation is internally created using setTarget:action: method.
*/
@property (nullable, strong, nonatomic) NSInvocation *invocation;
@end
@@ -0,0 +1,99 @@
//
// IQBarButtonItem.m
// https://github.com/hackiftekhar/IQKeyboardManager
// Copyright (c) 2013-16 Iftekhar Qurashi.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "IQBarButtonItem.h"
#import "IQKeyboardManagerConstantsInternal.h"
#import <UIKit/NSAttributedString.h>
@implementation IQBarButtonItem
+(void)initialize
{
[super initialize];
IQBarButtonItem *appearanceProxy = [self appearance];
NSArray <NSNumber*> *states = @[@(UIControlStateNormal),@(UIControlStateHighlighted),@(UIControlStateDisabled),@(UIControlStateSelected),@(UIControlStateApplication),@(UIControlStateReserved)];
for (NSNumber *state in states)
{
UIControlState controlState = [state unsignedIntegerValue];
[appearanceProxy setBackgroundImage:nil forState:controlState barMetrics:UIBarMetricsDefault];
[appearanceProxy setBackgroundImage:nil forState:controlState style:UIBarButtonItemStyleDone barMetrics:UIBarMetricsDefault];
[appearanceProxy setBackgroundImage:nil forState:controlState style:UIBarButtonItemStylePlain barMetrics:UIBarMetricsDefault];
[appearanceProxy setBackButtonBackgroundImage:nil forState:controlState barMetrics:UIBarMetricsDefault];
}
[appearanceProxy setTitlePositionAdjustment:UIOffsetZero forBarMetrics:UIBarMetricsDefault];
[appearanceProxy setBackgroundVerticalPositionAdjustment:0 forBarMetrics:UIBarMetricsDefault];
[appearanceProxy setBackButtonBackgroundVerticalPositionAdjustment:0 forBarMetrics:UIBarMetricsDefault];
}
-(void)setTintColor:(UIColor *)tintColor
{
[super setTintColor:tintColor];
//titleTextAttributes tweak is to overcome an issue comes with iOS11 where appearanceProxy set for NSForegroundColorAttributeName and bar button texts start appearing in appearance proxy color
NSMutableDictionary *textAttributes = [[self titleTextAttributesForState:UIControlStateNormal] mutableCopy]?:[NSMutableDictionary new];
textAttributes[NSForegroundColorAttributeName] = tintColor;
[self setTitleTextAttributes:textAttributes forState:UIControlStateNormal];
}
- (instancetype)initWithBarButtonSystemItem:(UIBarButtonSystemItem)systemItem target:(nullable id)target action:(nullable SEL)action
{
self = [super initWithBarButtonSystemItem:systemItem target:target action:action];
if (self)
{
_isSystemItem = YES;
}
return self;
}
-(void)setTarget:(nullable id)target action:(nullable SEL)action
{
NSInvocation *invocation = nil;
if (target && action)
{
invocation = [NSInvocation invocationWithMethodSignature:[target methodSignatureForSelector:action]];
invocation.target = target;
invocation.selector = action;
}
self.invocation = invocation;
}
-(void)dealloc
{
self.target = nil;
self.invocation.target = nil;
self.invocation = nil;
}
@end
@@ -0,0 +1,30 @@
//
// IQPreviousNextView.h
// https://github.com/hackiftekhar/IQKeyboardManager
// Copyright (c) 2013-16 Iftekhar Qurashi.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <UIKit/UIView.h>
/**
If you need to enable previous/next toolbar button with some complex hierarchy where your textFields are not in same view, then make the top view as IQPreviousNextView.
*/
@interface IQPreviousNextView : UIView
@end
@@ -0,0 +1,28 @@
//
// IQPreviousNextView.m
// https://github.com/hackiftekhar/IQKeyboardManager
// Copyright (c) 2013-16 Iftekhar Qurashi.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "IQPreviousNextView.h"
@implementation IQPreviousNextView
@end
@@ -0,0 +1,71 @@
//
// IQTitleBarButtonItem.h
// https://github.com/hackiftekhar/IQKeyboardManager
// Copyright (c) 2013-16 Iftekhar Qurashi.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "IQKeyboardManagerConstants.h"
#import "IQBarButtonItem.h"
#import <Foundation/NSObjCRuntime.h>
/**
BarButtonItem with title text.
*/
@interface IQTitleBarButtonItem : IQBarButtonItem
/**
Font to be used in bar button. Default is (system font 12.0 bold).
*/
@property(nullable, nonatomic, strong) UIFont *titleFont;
/**
titleColor to be used for displaying button text when displaying title (disabled state).
*/
@property(nullable, nonatomic, strong) UIColor *titleColor;
/**
selectableTitleColor to be used for displaying button text when button is enabled.
*/
@property(nullable, nonatomic, strong) UIColor *selectableTitleColor;
/**
Initialize with frame and title.
@param title Title of barButtonItem.
*/
-(nonnull instancetype)initWithTitle:(nullable NSString *)title NS_DESIGNATED_INITIALIZER;
/**
Unavailable. Please use initWithFrame:title: method
*/
-(nonnull instancetype)init NS_UNAVAILABLE;
/**
Unavailable. Please use initWithFrame:title: method
*/
-(nonnull instancetype)initWithCoder:(nullable NSCoder *)aDecoder NS_UNAVAILABLE;
/**
Unavailable. Please use initWithFrame:title: method
*/
+ (nonnull instancetype)new NS_UNAVAILABLE;
@end
@@ -0,0 +1,153 @@
//
// IQTitleBarButtonItem.m
// https://github.com/hackiftekhar/IQKeyboardManager
// Copyright (c) 2013-16 Iftekhar Qurashi.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "IQTitleBarButtonItem.h"
#import "IQKeyboardManagerConstants.h"
#import "IQKeyboardManagerConstantsInternal.h"
#import <UIKit/UILabel.h>
#import <UIKit/UIButton.h>
@interface IQTitleBarButtonItem ()
@property(nonatomic, strong) UIView *titleView;
@property(nonatomic, strong) UIButton *titleButton;
@end
@implementation IQTitleBarButtonItem
-(nonnull instancetype)initWithTitle:(nullable NSString *)title
{
self = [super init];
if (self)
{
_titleView = [[UIView alloc] init];
_titleView.backgroundColor = [UIColor clearColor];
_titleButton = [UIButton buttonWithType:UIButtonTypeSystem];
_titleButton.enabled = NO;
_titleButton.titleLabel.numberOfLines = 3;
[_titleButton setTitleColor:[UIColor colorWithRed:0.0 green:0.5 blue:1.0 alpha:1.0] forState:UIControlStateNormal];
[_titleButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateDisabled];
[_titleButton setBackgroundColor:[UIColor clearColor]];
[_titleButton.titleLabel setTextAlignment:NSTextAlignmentCenter];
[self setTitle:title];
[self setTitleFont:[UIFont systemFontOfSize:13.0]];
[_titleView addSubview:_titleButton];
#ifdef __IPHONE_11_0
if (@available(iOS 11.0, *))
{
CGFloat layoutDefaultLowPriority = UILayoutPriorityDefaultLow-1;
CGFloat layoutDefaultHighPriority = UILayoutPriorityDefaultHigh-1;
_titleView.translatesAutoresizingMaskIntoConstraints = NO;
[_titleView setContentHuggingPriority:layoutDefaultLowPriority forAxis:UILayoutConstraintAxisVertical];
[_titleView setContentHuggingPriority:layoutDefaultLowPriority forAxis:UILayoutConstraintAxisHorizontal];
[_titleView setContentCompressionResistancePriority:layoutDefaultHighPriority forAxis:UILayoutConstraintAxisVertical];
[_titleView setContentCompressionResistancePriority:layoutDefaultHighPriority forAxis:UILayoutConstraintAxisHorizontal];
_titleButton.translatesAutoresizingMaskIntoConstraints = NO;
[_titleButton setContentHuggingPriority:layoutDefaultLowPriority forAxis:UILayoutConstraintAxisVertical];
[_titleButton setContentHuggingPriority:layoutDefaultLowPriority forAxis:UILayoutConstraintAxisHorizontal];
[_titleButton setContentCompressionResistancePriority:layoutDefaultHighPriority forAxis:UILayoutConstraintAxisVertical];
[_titleButton setContentCompressionResistancePriority:layoutDefaultHighPriority forAxis:UILayoutConstraintAxisHorizontal];
NSLayoutConstraint *top = [NSLayoutConstraint constraintWithItem:_titleButton attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_titleView attribute:NSLayoutAttributeTop multiplier:1 constant:0];
NSLayoutConstraint *bottom = [NSLayoutConstraint constraintWithItem:_titleButton attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:_titleView attribute:NSLayoutAttributeBottom multiplier:1 constant:0];
NSLayoutConstraint *leading = [NSLayoutConstraint constraintWithItem:_titleButton attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:_titleView attribute:NSLayoutAttributeLeading multiplier:1 constant:0];
NSLayoutConstraint *trailing = [NSLayoutConstraint constraintWithItem:_titleButton attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:_titleView attribute:NSLayoutAttributeTrailing multiplier:1 constant:0];
[_titleView addConstraints:@[top,bottom,leading,trailing]];
}
else
#endif
{
_titleView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
_titleButton.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
}
self.customView = _titleView;
}
return self;
}
-(void)setTitleFont:(UIFont *)titleFont
{
_titleFont = titleFont;
if (titleFont)
{
_titleButton.titleLabel.font = titleFont;
}
else
{
_titleButton.titleLabel.font = [UIFont systemFontOfSize:13];
}
}
-(void)setTitle:(NSString *)title
{
[super setTitle:title];
[_titleButton setTitle:title forState:UIControlStateNormal];
}
-(void)setTitleColor:(UIColor*)titleColor
{
_titleColor = titleColor;
[_titleButton setTitleColor:_titleColor?:[UIColor lightGrayColor] forState:UIControlStateDisabled];
}
-(void)setSelectableTitleColor:(UIColor*)selectableTitleColor
{
_selectableTitleColor = selectableTitleColor;
[_titleButton setTitleColor:_selectableTitleColor?:[UIColor colorWithRed:0.0 green:0.5 blue:1.0 alpha:1.0] forState:UIControlStateNormal];
}
-(void)setInvocation:(NSInvocation *)invocation
{
[super setInvocation:invocation];
if (invocation.target == nil || invocation.selector == NULL)
{
self.enabled = NO;
_titleButton.enabled = NO;
[_titleButton removeTarget:nil action:NULL forControlEvents:UIControlEventTouchUpInside];
}
else
{
self.enabled = YES;
_titleButton.enabled = YES;
[_titleButton addTarget:invocation.target action:invocation.selector forControlEvents:UIControlEventTouchUpInside];
}
}
-(void)dealloc
{
self.customView = nil;
[_titleButton removeTarget:nil action:NULL forControlEvents:UIControlEventTouchUpInside];
_titleView = nil;
_titleButton = nil;
}
@end
@@ -0,0 +1,60 @@
//
// IQToolbar.h
// https://github.com/hackiftekhar/IQKeyboardManager
// Copyright (c) 2013-16 Iftekhar Qurashi.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "IQTitleBarButtonItem.h"
#import <UIKit/UIToolbar.h>
#import <UIKit/UIDevice.h>
/**
IQToolbar for IQKeyboardManager.
*/
@interface IQToolbar : UIToolbar <UIInputViewAudioFeedback>
/**
Previous bar button of toolbar.
*/
@property(nonnull, nonatomic, strong) IQBarButtonItem *previousBarButton;
/**
Next bar button of toolbar.
*/
@property(nonnull, nonatomic, strong) IQBarButtonItem *nextBarButton;
/**
Title bar button of toolbar.
*/
@property(nonnull, nonatomic, strong, readonly) IQTitleBarButtonItem *titleBarButton;
/**
Done bar button of toolbar.
*/
@property(nonnull, nonatomic, strong) IQBarButtonItem *doneBarButton;
/**
Fixed space bar button of toolbar.
*/
@property(nonnull, nonatomic, strong) IQBarButtonItem *fixedSpaceBarButton;
@end
@@ -0,0 +1,300 @@
//
// IQToolbar.m
// https://github.com/hackiftekhar/IQKeyboardManager
// Copyright (c) 2013-16 Iftekhar Qurashi.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "IQToolbar.h"
#import "IQKeyboardManagerConstantsInternal.h"
#import "IQUIView+Hierarchy.h"
#import <UIKit/UIButton.h>
#import <UIKit/UIAccessibility.h>
#import <UIKit/UIViewController.h>
@interface IQTitleBarButtonItem (PrivateAccessor)
@property(nonatomic, strong) UIButton *titleButton;
@end
@implementation IQToolbar
@synthesize previousBarButton = _previousBarButton;
@synthesize nextBarButton = _nextBarButton;
@synthesize titleBarButton = _titleBarButton;
@synthesize doneBarButton = _doneBarButton;
@synthesize fixedSpaceBarButton = _fixedSpaceBarButton;
+(void)initialize
{
[super initialize];
IQToolbar *appearanceProxy = [self appearance];
NSArray <NSNumber*> *positions = @[@(UIBarPositionAny),@(UIBarPositionBottom),@(UIBarPositionTop),@(UIBarPositionTopAttached)];
for (NSNumber *position in positions)
{
UIToolbarPosition toolbarPosition = [position unsignedIntegerValue];
[appearanceProxy setBackgroundImage:nil forToolbarPosition:toolbarPosition barMetrics:UIBarMetricsDefault];
[appearanceProxy setShadowImage:nil forToolbarPosition:toolbarPosition];
}
}
-(void)initialize
{
[self sizeToFit];
self.autoresizingMask = UIViewAutoresizingFlexibleWidth;// | UIViewAutoresizingFlexibleHeight;
self.translucent = YES;
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
[self initialize];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self)
{
[self initialize];
}
return self;
}
-(void)dealloc
{
self.items = nil;
_previousBarButton = nil;
_nextBarButton = nil;
_titleBarButton = nil;
_doneBarButton = nil;
_fixedSpaceBarButton = nil;
}
-(IQBarButtonItem *)previousBarButton
{
if (_previousBarButton == nil)
{
_previousBarButton = [[IQBarButtonItem alloc] initWithImage:nil style:UIBarButtonItemStylePlain target:nil action:nil];
_previousBarButton.accessibilityLabel = @"Toolbar Previous Button";
}
return _previousBarButton;
}
-(IQBarButtonItem *)nextBarButton
{
if (_nextBarButton == nil)
{
_nextBarButton = [[IQBarButtonItem alloc] initWithImage:nil style:UIBarButtonItemStylePlain target:nil action:nil];
_nextBarButton.accessibilityLabel = @"Toolbar Next Button";
}
return _nextBarButton;
}
-(IQTitleBarButtonItem *)titleBarButton
{
if (_titleBarButton == nil)
{
_titleBarButton = [[IQTitleBarButtonItem alloc] initWithTitle:nil];
_titleBarButton.accessibilityLabel = @"Toolbar Title Button";
}
return _titleBarButton;
}
-(IQBarButtonItem *)doneBarButton
{
if (_doneBarButton == nil)
{
_doneBarButton = [[IQBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:nil action:nil];
_doneBarButton.accessibilityLabel = @"Toolbar Done Button";
}
return _doneBarButton;
}
-(IQBarButtonItem *)fixedSpaceBarButton
{
if (_fixedSpaceBarButton == nil)
{
_fixedSpaceBarButton = [[IQBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
#ifdef __IPHONE_11_0
if (@available(iOS 10.0, *))
#else
if (IQ_IS_IOS10_OR_GREATER)
#endif
{
[_fixedSpaceBarButton setWidth:6];
}
else
{
[_fixedSpaceBarButton setWidth:20];
}
}
return _fixedSpaceBarButton;
}
-(CGSize)sizeThatFits:(CGSize)size
{
CGSize sizeThatFit = [super sizeThatFits:size];
sizeThatFit.height = 44;
return sizeThatFit;
}
-(void)setBarStyle:(UIBarStyle)barStyle
{
[super setBarStyle:barStyle];
if (self.titleBarButton.selectableTitleColor == nil)
{
if (barStyle == UIBarStyleDefault)
{
[self.titleBarButton.titleButton setTitleColor:[UIColor colorWithRed:0.0 green:0.5 blue:1.0 alpha:1.0] forState:UIControlStateNormal];
}
else
{
[self.titleBarButton.titleButton setTitleColor:[UIColor yellowColor] forState:UIControlStateNormal];
}
}
}
-(void)setTintColor:(UIColor *)tintColor
{
[super setTintColor:tintColor];
for (UIBarButtonItem *item in self.items)
{
[item setTintColor:tintColor];
}
}
-(void)layoutSubviews
{
[super layoutSubviews];
//If running on Xcode9 (iOS11) only then we'll validate for iOS version, otherwise for older versions of Xcode (iOS10 and below) we'll just execute the tweak
#ifdef __IPHONE_11_0
if (@available(iOS 11.0, *)) {}
else
#endif
{
CGRect leftRect = CGRectNull;
CGRect rightRect = CGRectNull;
BOOL isTitleBarButtonFound = NO;
NSArray<UIView*> *subviews = [self.subviews sortedArrayUsingComparator:^NSComparisonResult(UIView *view1, UIView *view2) {
CGFloat x1 = CGRectGetMinX(view1.frame);
CGFloat y1 = CGRectGetMinY(view1.frame);
CGFloat x2 = CGRectGetMinX(view2.frame);
CGFloat y2 = CGRectGetMinY(view2.frame);
if (x1 < x2) return NSOrderedAscending;
else if (x1 > x2) return NSOrderedDescending;
//Else both y are same so checking for x positions
else if (y1 < y2) return NSOrderedAscending;
else if (y1 > y2) return NSOrderedDescending;
else return NSOrderedSame;
}];
for (UIView *barButtonItemView in subviews)
{
if (isTitleBarButtonFound == YES)
{
rightRect = barButtonItemView.frame;
break;
}
else if (barButtonItemView == self.titleBarButton.customView)
{
isTitleBarButtonFound = YES;
}
//If it's UIToolbarButton or UIToolbarTextButton (which actually UIBarButtonItem)
else if ([barButtonItemView isKindOfClass:[UIControl class]])
{
leftRect = barButtonItemView.frame;
}
}
CGFloat titleMargin = 16;
CGFloat maxWidth = CGRectGetWidth(self.frame) - titleMargin*2 - (CGRectIsNull(leftRect)?0:CGRectGetMaxX(leftRect)) - (CGRectIsNull(rightRect)?0:CGRectGetWidth(self.frame)-CGRectGetMinX(rightRect));
CGFloat maxHeight = self.frame.size.height;
CGSize sizeThatFits = [self.titleBarButton.customView sizeThatFits:CGSizeMake(maxWidth, maxHeight)];
CGRect titleRect = CGRectZero;
CGFloat x = titleMargin;
if (sizeThatFits.width > 0 && sizeThatFits.height > 0)
{
CGFloat width = MIN(sizeThatFits.width, maxWidth);
CGFloat height = MIN(sizeThatFits.height, maxHeight);
if (CGRectIsNull(leftRect) == false)
{
x = titleMargin + CGRectGetMaxX(leftRect) + ((maxWidth - width)/2);
}
CGFloat y = (maxHeight - height)/2;
titleRect = CGRectMake(x, y, width, height);
}
else
{
if (CGRectIsNull(leftRect) == false)
{
x = titleMargin + CGRectGetMaxX(leftRect);
}
CGFloat width = CGRectGetWidth(self.frame) - titleMargin*2 - (CGRectIsNull(leftRect)?0:CGRectGetMaxX(leftRect)) - (CGRectIsNull(rightRect)?0:CGRectGetWidth(self.frame)-CGRectGetMinX(rightRect));
titleRect = CGRectMake(x, 0, width, maxHeight);
}
self.titleBarButton.customView.frame = titleRect;
}
}
#pragma mark - UIInputViewAudioFeedback delegate
- (BOOL) enableInputClicksWhenVisible
{
return YES;
}
@end
@@ -0,0 +1,150 @@
//
// IQUIView+IQKeyboardToolbar.h
// https://github.com/hackiftekhar/IQKeyboardManager
// Copyright (c) 2013-16 Iftekhar Qurashi.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "IQToolbar.h"
#import <UIKit/UIView.h>
#import <UIKit/UIImage.h>
@interface IQBarButtonItemConfiguration : NSObject
-(instancetype)initWithBarButtonSystemItem:(UIBarButtonSystemItem)barButtonSystemItem action:(nullable SEL)action;
-(instancetype)initWithImage:(nonnull UIImage*)image action:(nullable SEL)action;
-(instancetype)initWithTitle:(nonnull NSString*)title action:(nullable SEL)action;
@property (readonly, nonatomic) UIBarButtonSystemItem barButtonSystemItem; //System Item to be used to instantiate bar button
@property (readonly, nonatomic, nullable) UIImage *image; //Image to show on bar button item if it's not a system item.
@property (readonly, nonatomic, nullable) NSString *title; //Title to show on bar button item if it's not a system item.
@property (readonly, nonatomic, nullable) SEL action; //action for bar button item. Usually 'doneAction:(IQBarButtonItem*)item'.
@end
@interface UIImage (IQKeyboardToolbarNextPreviousImage)
+(UIImage*)keyboardPreviousiOS9Image;
+(UIImage*)keyboardNextiOS9Image;
+(UIImage*)keyboardPreviousiOS10Image;
+(UIImage*)keyboardNextiOS10Image;
+(UIImage*)keyboardPreviousImage;
+(UIImage*)keyboardNextImage;
@end
/**
UIView category methods to add IQToolbar on UIKeyboard.
*/
@interface UIView (IQToolbarAddition)
///-------------------------
/// @name Toolbar Title
///-------------------------
/**
IQToolbar references for better customization control.
*/
@property (readonly, nonatomic, nonnull) IQToolbar *keyboardToolbar;
/**
If `shouldHideToolbarPlaceholder` is YES, then title will not be added to the toolbar. Default to NO.
*/
@property (assign, nonatomic) BOOL shouldHideToolbarPlaceholder;
@property (assign, nonatomic) BOOL shouldHidePlaceholderText __attribute__((deprecated("This is renamed to `shouldHideToolbarPlaceholder` for more clear naming.")));
/**
`toolbarPlaceholder` to override default `placeholder` text when drawing text on toolbar.
*/
@property (nullable, strong, nonatomic) NSString* toolbarPlaceholder;
@property (nullable, strong, nonatomic) NSString* placeholderText __attribute__((deprecated("This is renamed to `toolbarPlaceholder` for more clear naming.")));
/**
`drawingToolbarPlaceholder` will be actual text used to draw on toolbar. This would either `placeholder` or `toolbarPlaceholder`.
*/
@property (nullable, strong, nonatomic, readonly) NSString* drawingToolbarPlaceholder;
@property (nullable, strong, nonatomic, readonly) NSString* drawingPlaceholderText __attribute__((deprecated("This is renamed to `drawingToolbarPlaceholder` for more clear naming.")));
///-------------
/// MARK: Common
///-------------
- (void)addKeyboardToolbarWithTarget:(nullable id)target titleText:(nullable NSString*)titleText rightBarButtonConfiguration:(nullable IQBarButtonItemConfiguration*)rightBarButtonConfiguration previousBarButtonConfiguration:(nullable IQBarButtonItemConfiguration*)previousBarButtonConfiguration nextBarButtonConfiguration:(nullable IQBarButtonItemConfiguration*)nextBarButtonConfiguration;
///------------
/// @name Done
///------------
- (void)addDoneOnKeyboardWithTarget:(nullable id)target action:(nullable SEL)action;
- (void)addDoneOnKeyboardWithTarget:(nullable id)target action:(nullable SEL)action shouldShowPlaceholder:(BOOL)shouldShowPlaceholder;
- (void)addDoneOnKeyboardWithTarget:(nullable id)target action:(nullable SEL)action titleText:(nullable NSString*)titleText;
///------------
/// @name Right
///------------
- (void)addRightButtonOnKeyboardWithText:(nullable NSString*)text target:(nullable id)target action:(nullable SEL)action;
- (void)addRightButtonOnKeyboardWithText:(nullable NSString*)text target:(nullable id)target action:(nullable SEL)action shouldShowPlaceholder:(BOOL)shouldShowPlaceholder;
- (void)addRightButtonOnKeyboardWithText:(nullable NSString*)text target:(nullable id)target action:(nullable SEL)action titleText:(nullable NSString*)titleText;
- (void)addRightButtonOnKeyboardWithImage:(nullable UIImage*)image target:(nullable id)target action:(nullable SEL)action;
- (void)addRightButtonOnKeyboardWithImage:(nullable UIImage*)image target:(nullable id)target action:(nullable SEL)action shouldShowPlaceholder:(BOOL)shouldShowPlaceholder;
- (void)addRightButtonOnKeyboardWithImage:(nullable UIImage*)image target:(nullable id)target action:(nullable SEL)action titleText:(nullable NSString*)titleText;
///------------------
/// @name Cancel/Done
///------------------
- (void)addCancelDoneOnKeyboardWithTarget:(nullable id)target cancelAction:(nullable SEL)cancelAction doneAction:(nullable SEL)doneAction;
- (void)addCancelDoneOnKeyboardWithTarget:(nullable id)target cancelAction:(nullable SEL)cancelAction doneAction:(nullable SEL)doneAction shouldShowPlaceholder:(BOOL)shouldShowPlaceholder;
- (void)addCancelDoneOnKeyboardWithTarget:(nullable id)target cancelAction:(nullable SEL)cancelAction doneAction:(nullable SEL)doneAction titleText:(nullable NSString*)titleText;
///-----------------
/// @name Right/Left
///-----------------
- (void)addLeftRightOnKeyboardWithTarget:(nullable id)target leftButtonTitle:(nullable NSString*)leftButtonTitle rightButtonTitle:(nullable NSString*)rightButtonTitle leftButtonAction:(nullable SEL)leftButtonAction rightButtonAction:(nullable SEL)rightButtonAction;
- (void)addLeftRightOnKeyboardWithTarget:(nullable id)target leftButtonTitle:(nullable NSString*)leftButtonTitle rightButtonTitle:(nullable NSString*)rightButtonTitle leftButtonAction:(nullable SEL)leftButtonAction rightButtonAction:(nullable SEL)rightButtonAction shouldShowPlaceholder:(BOOL)shouldShowPlaceholder;
- (void)addLeftRightOnKeyboardWithTarget:(nullable id)target leftButtonTitle:(nullable NSString*)leftButtonTitle rightButtonTitle:(nullable NSString*)rightButtonTitle leftButtonAction:(nullable SEL)leftButtonAction rightButtonAction:(nullable SEL)rightButtonAction titleText:(nullable NSString*)titleText;
///-------------------------
/// @name Previous/Next/Done
///-------------------------
- (void)addPreviousNextDoneOnKeyboardWithTarget:(nullable id)target previousAction:(nullable SEL)previousAction nextAction:(nullable SEL)nextAction doneAction:(nullable SEL)doneAction;
- (void)addPreviousNextDoneOnKeyboardWithTarget:(nullable id)target previousAction:(nullable SEL)previousAction nextAction:(nullable SEL)nextAction doneAction:(nullable SEL)doneAction shouldShowPlaceholder:(BOOL)shouldShowPlaceholder;
- (void)addPreviousNextDoneOnKeyboardWithTarget:(nullable id)target previousAction:(nullable SEL)previousAction nextAction:(nullable SEL)nextAction doneAction:(nullable SEL)doneAction titleText:(nullable NSString*)titleText;
///--------------------------
/// @name Previous/Next/Right
///--------------------------
- (void)addPreviousNextRightOnKeyboardWithTarget:(nullable id)target rightButtonTitle:(nullable NSString*)rightButtonTitle previousAction:(nullable SEL)previousAction nextAction:(nullable SEL)nextAction rightButtonAction:(nullable SEL)rightButtonAction;
- (void)addPreviousNextRightOnKeyboardWithTarget:(nullable id)target rightButtonTitle:(nullable NSString*)rightButtonTitle previousAction:(nullable SEL)previousAction nextAction:(nullable SEL)nextAction rightButtonAction:(nullable SEL)rightButtonAction shouldShowPlaceholder:(BOOL)shouldShowPlaceholder;
- (void)addPreviousNextRightOnKeyboardWithTarget:(nullable id)target rightButtonTitle:(nullable NSString*)rightButtonTitle previousAction:(nullable SEL)previousAction nextAction:(nullable SEL)nextAction rightButtonAction:(nullable SEL)rightButtonAction titleText:(nullable NSString*)titleText;
- (void)addPreviousNextRightOnKeyboardWithTarget:(nullable id)target rightButtonImage:(nullable UIImage*)rightButtonImage previousAction:(nullable SEL)previousAction nextAction:(nullable SEL)nextAction rightButtonAction:(nullable SEL)rightButtonAction;
- (void)addPreviousNextRightOnKeyboardWithTarget:(nullable id)target rightButtonImage:(nullable UIImage*)rightButtonImage previousAction:(nullable SEL)previousAction nextAction:(nullable SEL)nextAction rightButtonAction:(nullable SEL)rightButtonAction shouldShowPlaceholder:(BOOL)shouldShowPlaceholder;
- (void)addPreviousNextRightOnKeyboardWithTarget:(nullable id)target rightButtonImage:(nullable UIImage*)rightButtonImage previousAction:(nullable SEL)previousAction nextAction:(nullable SEL)nextAction rightButtonAction:(nullable SEL)rightButtonAction titleText:(nullable NSString*)titleText;
@end
@@ -0,0 +1,676 @@
//
// IQUIView+IQKeyboardToolbar.m
// https://github.com/hackiftekhar/IQKeyboardManager
// Copyright (c) 2013-16 Iftekhar Qurashi.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "IQUIView+IQKeyboardToolbar.h"
#import "IQKeyboardManagerConstantsInternal.h"
#import "IQKeyboardManager.h"
#import <objc/runtime.h>
#import <UIKit/UIImage.h>
#import <UIKit/UILabel.h>
#import <UIKit/UIAccessibility.h>
@implementation IQBarButtonItemConfiguration
-(instancetype)initWithBarButtonSystemItem:(UIBarButtonSystemItem)barButtonSystemItem action:(SEL)action
{
self = [super init];
if (self) {
_barButtonSystemItem = barButtonSystemItem;
_action = action;
}
return self;
}
-(instancetype)initWithImage:(UIImage *)image action:(SEL)action
{
self = [super init];
if (self) {
_image = image;
_action = action;
}
return self;
}
-(instancetype)initWithTitle:(NSString *)title action:(SEL)action
{
self = [super init];
if (self) {
_title = title;
_action = action;
}
return self;
}
@end
@implementation UIImage (IQKeyboardToolbarNextPreviousImage)
+(UIImage*)keyboardPreviousiOS9Image
{
static UIImage *keyboardPreviousiOS9Image = nil;
if (keyboardPreviousiOS9Image == nil)
{
// Get the top level "bundle" which may actually be the framework
NSBundle *mainBundle = [NSBundle bundleForClass:[IQKeyboardManager class]];
// Check to see if the resource bundle exists inside the top level bundle
NSBundle *resourcesBundle = [NSBundle bundleWithPath:[mainBundle pathForResource:@"IQKeyboardManager" ofType:@"bundle"]];
if (resourcesBundle == nil) {
resourcesBundle = mainBundle;
}
keyboardPreviousiOS9Image = [UIImage imageNamed:@"IQButtonBarArrowLeft" inBundle:resourcesBundle compatibleWithTraitCollection:nil];;
//Support for RTL languages like Arabic, Persia etc... (Bug ID: #448)
#ifdef __IPHONE_11_0
if (@available(iOS 9.0, *)) {
#endif
if ([UIImage instancesRespondToSelector:@selector(imageFlippedForRightToLeftLayoutDirection)])
{
keyboardPreviousiOS9Image = [keyboardPreviousiOS9Image imageFlippedForRightToLeftLayoutDirection];
}
#ifdef __IPHONE_11_0
}
#endif
}
return keyboardPreviousiOS9Image;
}
+(UIImage*)keyboardNextiOS9Image
{
static UIImage *keyboardNextiOS9Image = nil;
if (keyboardNextiOS9Image == nil)
{
// Get the top level "bundle" which may actually be the framework
NSBundle *mainBundle = [NSBundle bundleForClass:[IQKeyboardManager class]];
// Check to see if the resource bundle exists inside the top level bundle
NSBundle *resourcesBundle = [NSBundle bundleWithPath:[mainBundle pathForResource:@"IQKeyboardManager" ofType:@"bundle"]];
if (resourcesBundle == nil) {
resourcesBundle = mainBundle;
}
keyboardNextiOS9Image = [UIImage imageNamed:@"IQButtonBarArrowRight" inBundle:resourcesBundle compatibleWithTraitCollection:nil];
//Support for RTL languages like Arabic, Persia etc... (Bug ID: #448)
#ifdef __IPHONE_11_0
if (@available(iOS 9.0, *)) {
#endif
if ([UIImage instancesRespondToSelector:@selector(imageFlippedForRightToLeftLayoutDirection)])
{
keyboardNextiOS9Image = [keyboardNextiOS9Image imageFlippedForRightToLeftLayoutDirection];
}
#ifdef __IPHONE_11_0
}
#endif
}
return keyboardNextiOS9Image;
}
+(UIImage*)keyboardPreviousiOS10Image
{
static UIImage *keyboardPreviousiOS10Image = nil;
if (keyboardPreviousiOS10Image == nil)
{
// Get the top level "bundle" which may actually be the framework
NSBundle *mainBundle = [NSBundle bundleForClass:[IQKeyboardManager class]];
// Check to see if the resource bundle exists inside the top level bundle
NSBundle *resourcesBundle = [NSBundle bundleWithPath:[mainBundle pathForResource:@"IQKeyboardManager" ofType:@"bundle"]];
if (resourcesBundle == nil) {
resourcesBundle = mainBundle;
}
keyboardPreviousiOS10Image = [UIImage imageNamed:@"IQButtonBarArrowUp" inBundle:resourcesBundle compatibleWithTraitCollection:nil];
//Support for RTL languages like Arabic, Persia etc... (Bug ID: #448)
#ifdef __IPHONE_11_0
if (@available(iOS 9.0, *)) {
#endif
if ([UIImage instancesRespondToSelector:@selector(imageFlippedForRightToLeftLayoutDirection)])
{
keyboardPreviousiOS10Image = [keyboardPreviousiOS10Image imageFlippedForRightToLeftLayoutDirection];
}
#ifdef __IPHONE_11_0
}
#endif
}
return keyboardPreviousiOS10Image;
}
+(UIImage*)keyboardNextiOS10Image
{
static UIImage *keyboardNextiOS10Image = nil;
if (keyboardNextiOS10Image == nil)
{
// Get the top level "bundle" which may actually be the framework
NSBundle *mainBundle = [NSBundle bundleForClass:[IQKeyboardManager class]];
// Check to see if the resource bundle exists inside the top level bundle
NSBundle *resourcesBundle = [NSBundle bundleWithPath:[mainBundle pathForResource:@"IQKeyboardManager" ofType:@"bundle"]];
if (resourcesBundle == nil) {
resourcesBundle = mainBundle;
}
keyboardNextiOS10Image = [UIImage imageNamed:@"IQButtonBarArrowDown" inBundle:resourcesBundle compatibleWithTraitCollection:nil];
//Support for RTL languages like Arabic, Persia etc... (Bug ID: #448)
#ifdef __IPHONE_11_0
if (@available(iOS 9.0, *)) {
#endif
if ([UIImage instancesRespondToSelector:@selector(imageFlippedForRightToLeftLayoutDirection)])
{
keyboardNextiOS10Image = [keyboardNextiOS10Image imageFlippedForRightToLeftLayoutDirection];
}
#ifdef __IPHONE_11_0
}
#endif
}
return keyboardNextiOS10Image;
}
+(UIImage*)keyboardPreviousImage
{
#ifdef __IPHONE_11_0
if (@available(iOS 10.0, *))
#else
if (IQ_IS_IOS10_OR_GREATER)
#endif
{
return [UIImage keyboardPreviousiOS10Image];
}
else
{
return [UIImage keyboardPreviousiOS9Image];
}
}
+(UIImage*)keyboardNextImage
{
#ifdef __IPHONE_11_0
if (@available(iOS 10.0, *))
#else
if (IQ_IS_IOS10_OR_GREATER)
#endif
{
return [UIImage keyboardNextiOS10Image];
}
else
{
return [UIImage keyboardNextiOS9Image];
}
}
@end
/*UIKeyboardToolbar Category implementation*/
@implementation UIView (IQToolbarAddition)
-(IQToolbar *)keyboardToolbar
{
IQToolbar *keyboardToolbar = nil;
if ([[self inputAccessoryView] isKindOfClass:[IQToolbar class]])
{
keyboardToolbar = [self inputAccessoryView];
}
else
{
keyboardToolbar = objc_getAssociatedObject(self, @selector(keyboardToolbar));
if (keyboardToolbar == nil)
{
keyboardToolbar = [[IQToolbar alloc] init];
objc_setAssociatedObject(self, @selector(keyboardToolbar), keyboardToolbar, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
}
return keyboardToolbar;
}
-(void)setShouldHideToolbarPlaceholder:(BOOL)shouldHideToolbarPlaceholder
{
objc_setAssociatedObject(self, @selector(shouldHideToolbarPlaceholder), @(shouldHideToolbarPlaceholder), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
self.keyboardToolbar.titleBarButton.title = self.drawingToolbarPlaceholder;
}
-(BOOL)shouldHideToolbarPlaceholder
{
NSNumber *shouldHideToolbarPlaceholder = objc_getAssociatedObject(self, @selector(shouldHideToolbarPlaceholder));
return [shouldHideToolbarPlaceholder boolValue];
}
-(void)setShouldHidePlaceholderText:(BOOL)shouldHidePlaceholderText
{
[self setShouldHideToolbarPlaceholder:shouldHidePlaceholderText];
}
-(BOOL)shouldHidePlaceholderText
{
return [self shouldHideToolbarPlaceholder];
}
-(void)setToolbarPlaceholder:(NSString *)toolbarPlaceholder
{
objc_setAssociatedObject(self, @selector(toolbarPlaceholder), toolbarPlaceholder, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
self.keyboardToolbar.titleBarButton.title = self.drawingToolbarPlaceholder;
}
-(NSString *)toolbarPlaceholder
{
NSString *toolbarPlaceholder = objc_getAssociatedObject(self, @selector(toolbarPlaceholder));
return toolbarPlaceholder;
}
-(void)setPlaceholderText:(NSString*)placeholderText
{
[self setToolbarPlaceholder:placeholderText];
}
-(NSString*)placeholderText
{
return [self toolbarPlaceholder];
}
-(NSString *)drawingToolbarPlaceholder
{
if (self.shouldHideToolbarPlaceholder)
{
return nil;
}
else if (self.toolbarPlaceholder.length != 0)
{
return self.toolbarPlaceholder;
}
else if ([self respondsToSelector:@selector(placeholder)])
{
return [(UITextField*)self placeholder];
}
else
{
return nil;
}
}
-(NSString*)drawingPlaceholderText
{
return [self drawingToolbarPlaceholder];
}
#pragma mark - Private helper
+(IQBarButtonItem*)flexibleBarButtonItem
{
static IQBarButtonItem *nilButton = nil;
if (nilButton == nil)
{
nilButton = [[IQBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
}
return nilButton;
}
#pragma mark - Common
- (void)addKeyboardToolbarWithTarget:(id)target titleText:(NSString*)titleText rightBarButtonConfiguration:(IQBarButtonItemConfiguration*)rightBarButtonConfiguration previousBarButtonConfiguration:(IQBarButtonItemConfiguration*)previousBarButtonConfiguration nextBarButtonConfiguration:(IQBarButtonItemConfiguration*)nextBarButtonConfiguration
{
//If can't set InputAccessoryView. Then return
if (![self respondsToSelector:@selector(setInputAccessoryView:)]) return;
// Creating a toolBar for phoneNumber keyboard
IQToolbar *toolbar = self.keyboardToolbar;
NSMutableArray<UIBarButtonItem*> *items = [[NSMutableArray alloc] init];
if(previousBarButtonConfiguration)
{
IQBarButtonItem *prev = toolbar.previousBarButton;
if (prev.isSystemItem == NO && (previousBarButtonConfiguration.image || previousBarButtonConfiguration.title))
{
prev.title = previousBarButtonConfiguration.title;
prev.image = previousBarButtonConfiguration.image;
prev.target = target;
prev.action = previousBarButtonConfiguration.action;
}
else if (previousBarButtonConfiguration.image)
{
prev = [[IQBarButtonItem alloc] initWithImage:previousBarButtonConfiguration.image style:UIBarButtonItemStylePlain target:target action:previousBarButtonConfiguration.action];
prev.invocation = toolbar.previousBarButton.invocation;
prev.accessibilityLabel = toolbar.previousBarButton.accessibilityLabel;
toolbar.previousBarButton = prev;
}
else if (previousBarButtonConfiguration.title)
{
prev = [[IQBarButtonItem alloc] initWithTitle:previousBarButtonConfiguration.title style:UIBarButtonItemStylePlain target:target action:previousBarButtonConfiguration.action];
prev.invocation = toolbar.previousBarButton.invocation;
prev.accessibilityLabel = toolbar.previousBarButton.accessibilityLabel;
toolbar.previousBarButton = prev;
}
else
{
prev = [[IQBarButtonItem alloc] initWithBarButtonSystemItem:previousBarButtonConfiguration.barButtonSystemItem target:target action:previousBarButtonConfiguration.action];
prev.invocation = toolbar.previousBarButton.invocation;
prev.accessibilityLabel = toolbar.previousBarButton.accessibilityLabel;
toolbar.previousBarButton = prev;
}
[items addObject:prev];
}
if (previousBarButtonConfiguration != nil && nextBarButtonConfiguration != nil)
{
[items addObject:toolbar.fixedSpaceBarButton];
}
if(nextBarButtonConfiguration)
{
IQBarButtonItem *next = toolbar.nextBarButton;
if (next.isSystemItem == NO && (nextBarButtonConfiguration.image || nextBarButtonConfiguration.title))
{
next.title = nextBarButtonConfiguration.title;
next.image = nextBarButtonConfiguration.image;
next.target = target;
next.action = nextBarButtonConfiguration.action;
}
else if (nextBarButtonConfiguration.image)
{
next = [[IQBarButtonItem alloc] initWithImage:nextBarButtonConfiguration.image style:UIBarButtonItemStylePlain target:target action:nextBarButtonConfiguration.action];
next.invocation = toolbar.nextBarButton.invocation;
next.accessibilityLabel = toolbar.nextBarButton.accessibilityLabel;
toolbar.nextBarButton = next;
}
else if (nextBarButtonConfiguration.title)
{
next = [[IQBarButtonItem alloc] initWithTitle:nextBarButtonConfiguration.title style:UIBarButtonItemStylePlain target:target action:nextBarButtonConfiguration.action];
next.invocation = toolbar.nextBarButton.invocation;
next.accessibilityLabel = toolbar.nextBarButton.accessibilityLabel;
toolbar.nextBarButton = next;
}
else
{
next = [[IQBarButtonItem alloc] initWithBarButtonSystemItem:nextBarButtonConfiguration.barButtonSystemItem target:target action:nextBarButtonConfiguration.action];
next.invocation = toolbar.nextBarButton.invocation;
next.accessibilityLabel = toolbar.nextBarButton.accessibilityLabel;
toolbar.nextBarButton = next;
}
[items addObject:next];
}
//Title
{
//Flexible space
[items addObject:[[self class] flexibleBarButtonItem]];
//Title button
toolbar.titleBarButton.title = titleText;
#ifdef __IPHONE_11_0
if (@available(iOS 11.0, *)) {}
else
#endif
{
toolbar.titleBarButton.customView.frame = CGRectZero;
}
[items addObject:toolbar.titleBarButton];
//Flexible space
[items addObject:[[self class] flexibleBarButtonItem]];
}
if(rightBarButtonConfiguration)
{
IQBarButtonItem *done = toolbar.doneBarButton;
if (done.isSystemItem == NO && (rightBarButtonConfiguration.image || rightBarButtonConfiguration.title))
{
done.title = rightBarButtonConfiguration.title;
done.image = rightBarButtonConfiguration.image;
done.target = target;
done.action = rightBarButtonConfiguration.action;
}
else if (rightBarButtonConfiguration.image)
{
done = [[IQBarButtonItem alloc] initWithImage:rightBarButtonConfiguration.image style:UIBarButtonItemStylePlain target:target action:rightBarButtonConfiguration.action];
done.invocation = toolbar.doneBarButton.invocation;
done.accessibilityLabel = toolbar.doneBarButton.accessibilityLabel;
toolbar.doneBarButton = done;
}
else if (rightBarButtonConfiguration.title)
{
done = [[IQBarButtonItem alloc] initWithTitle:rightBarButtonConfiguration.title style:UIBarButtonItemStylePlain target:target action:rightBarButtonConfiguration.action];
done.invocation = toolbar.doneBarButton.invocation;
done.accessibilityLabel = toolbar.doneBarButton.accessibilityLabel;
toolbar.doneBarButton = done;
}
else
{
done = [[IQBarButtonItem alloc] initWithBarButtonSystemItem:rightBarButtonConfiguration.barButtonSystemItem target:target action:rightBarButtonConfiguration.action];
done.invocation = toolbar.doneBarButton.invocation;
done.accessibilityLabel = toolbar.doneBarButton.accessibilityLabel;
toolbar.doneBarButton = done;
}
[items addObject:done];
}
// Adding button to toolBar.
[toolbar setItems:items];
// Setting toolbar to keyboard.
[(UITextField*)self setInputAccessoryView:toolbar];
if ([self respondsToSelector:@selector(keyboardAppearance)])
{
switch ([(UITextField*)self keyboardAppearance])
{
case UIKeyboardAppearanceDark: toolbar.barStyle = UIBarStyleBlack; break;
default: toolbar.barStyle = UIBarStyleDefault; break;
}
}
}
#pragma mark - Right
- (void)addRightButtonOnKeyboardWithText:(NSString*)text target:(id)target action:(SEL)action
{
[self addRightButtonOnKeyboardWithText:text target:target action:action titleText:nil];
}
- (void)addRightButtonOnKeyboardWithText:(NSString*)text target:(id)target action:(SEL)action shouldShowPlaceholder:(BOOL)shouldShowPlaceholder
{
[self addRightButtonOnKeyboardWithText:text target:target action:action titleText:(shouldShowPlaceholder?[self drawingToolbarPlaceholder]:nil)];
}
- (void)addRightButtonOnKeyboardWithText:(NSString*)text target:(id)target action:(SEL)action titleText:(NSString*)titleText
{
IQBarButtonItemConfiguration *rightConfiguration = [[IQBarButtonItemConfiguration alloc] initWithTitle:text action:action];
[self addKeyboardToolbarWithTarget:target titleText:titleText rightBarButtonConfiguration:rightConfiguration previousBarButtonConfiguration:nil nextBarButtonConfiguration:nil];
}
- (void)addRightButtonOnKeyboardWithImage:(UIImage*)image target:(id)target action:(SEL)action
{
[self addRightButtonOnKeyboardWithImage:image target:target action:action titleText:nil];
}
- (void)addRightButtonOnKeyboardWithImage:(UIImage*)image target:(id)target action:(SEL)action shouldShowPlaceholder:(BOOL)shouldShowPlaceholder
{
[self addRightButtonOnKeyboardWithImage:image target:target action:action titleText:(shouldShowPlaceholder?[self drawingToolbarPlaceholder]:nil)];
}
- (void)addRightButtonOnKeyboardWithImage:(UIImage*)image target:(id)target action:(SEL)action titleText:(NSString*)titleText
{
IQBarButtonItemConfiguration *rightConfiguration = [[IQBarButtonItemConfiguration alloc] initWithImage:image action:action];
[self addKeyboardToolbarWithTarget:target titleText:titleText rightBarButtonConfiguration:rightConfiguration previousBarButtonConfiguration:nil nextBarButtonConfiguration:nil];
}
-(void)addDoneOnKeyboardWithTarget:(id)target action:(SEL)action
{
[self addDoneOnKeyboardWithTarget:target action:action titleText:nil];
}
-(void)addDoneOnKeyboardWithTarget:(id)target action:(SEL)action shouldShowPlaceholder:(BOOL)shouldShowPlaceholder
{
[self addDoneOnKeyboardWithTarget:target action:action titleText:(shouldShowPlaceholder?[self drawingToolbarPlaceholder]:nil)];
}
- (void)addDoneOnKeyboardWithTarget:(id)target action:(SEL)action titleText:(NSString*)titleText
{
IQBarButtonItemConfiguration *rightConfiguration = [[IQBarButtonItemConfiguration alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone action:action];
[self addKeyboardToolbarWithTarget:target titleText:titleText rightBarButtonConfiguration:rightConfiguration previousBarButtonConfiguration:nil nextBarButtonConfiguration:nil];
}
- (void)addLeftRightOnKeyboardWithTarget:(id)target leftButtonTitle:(NSString*)leftTitle rightButtonTitle:(NSString*)rightTitle leftButtonAction:(SEL)leftAction rightButtonAction:(SEL)rightAction
{
[self addLeftRightOnKeyboardWithTarget:target leftButtonTitle:leftTitle rightButtonTitle:rightTitle leftButtonAction:leftAction rightButtonAction:rightAction titleText:nil];
}
- (void)addLeftRightOnKeyboardWithTarget:(id)target leftButtonTitle:(NSString*)leftTitle rightButtonTitle:(NSString*)rightTitle leftButtonAction:(SEL)leftAction rightButtonAction:(SEL)rightAction shouldShowPlaceholder:(BOOL)shouldShowPlaceholder
{
[self addLeftRightOnKeyboardWithTarget:target leftButtonTitle:leftTitle rightButtonTitle:rightTitle leftButtonAction:leftAction rightButtonAction:rightAction titleText:(shouldShowPlaceholder?[self drawingToolbarPlaceholder]:nil)];
}
- (void)addLeftRightOnKeyboardWithTarget:(id)target leftButtonTitle:(NSString*)leftTitle rightButtonTitle:(NSString*)rightTitle leftButtonAction:(SEL)leftAction rightButtonAction:(SEL)rightAction titleText:(NSString*)titleText
{
IQBarButtonItemConfiguration *leftConfiguration = [[IQBarButtonItemConfiguration alloc] initWithTitle:leftTitle action:leftAction];
IQBarButtonItemConfiguration *rightConfiguration = [[IQBarButtonItemConfiguration alloc] initWithTitle:rightTitle action:rightAction];
[self addKeyboardToolbarWithTarget:target titleText:titleText rightBarButtonConfiguration:rightConfiguration previousBarButtonConfiguration:leftConfiguration nextBarButtonConfiguration:nil];
}
-(void)addCancelDoneOnKeyboardWithTarget:(id)target cancelAction:(SEL)cancelAction doneAction:(SEL)doneAction
{
[self addCancelDoneOnKeyboardWithTarget:target cancelAction:cancelAction doneAction:doneAction titleText:nil];
}
-(void)addCancelDoneOnKeyboardWithTarget:(id)target cancelAction:(SEL)cancelAction doneAction:(SEL)doneAction shouldShowPlaceholder:(BOOL)shouldShowPlaceholder
{
[self addCancelDoneOnKeyboardWithTarget:target cancelAction:cancelAction doneAction:doneAction titleText:(shouldShowPlaceholder?[self drawingToolbarPlaceholder]:nil)];
}
- (void)addCancelDoneOnKeyboardWithTarget:(id)target cancelAction:(SEL)cancelAction doneAction:(SEL)doneAction titleText:(NSString*)titleText
{
IQBarButtonItemConfiguration *leftConfiguration = [[IQBarButtonItemConfiguration alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel action:cancelAction];
IQBarButtonItemConfiguration *rightConfiguration = [[IQBarButtonItemConfiguration alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone action:doneAction];
[self addKeyboardToolbarWithTarget:target titleText:titleText rightBarButtonConfiguration:rightConfiguration previousBarButtonConfiguration:leftConfiguration nextBarButtonConfiguration:nil];
}
-(void)addPreviousNextDoneOnKeyboardWithTarget:(id)target previousAction:(SEL)previousAction nextAction:(SEL)nextAction doneAction:(SEL)doneAction
{
[self addPreviousNextDoneOnKeyboardWithTarget:target previousAction:previousAction nextAction:nextAction doneAction:doneAction titleText:nil];
}
-(void)addPreviousNextDoneOnKeyboardWithTarget:(id)target previousAction:(SEL)previousAction nextAction:(SEL)nextAction doneAction:(SEL)doneAction shouldShowPlaceholder:(BOOL)shouldShowPlaceholder
{
[self addPreviousNextDoneOnKeyboardWithTarget:target previousAction:previousAction nextAction:nextAction doneAction:doneAction titleText:(shouldShowPlaceholder?[self drawingToolbarPlaceholder]:nil)];
}
- (void)addPreviousNextDoneOnKeyboardWithTarget:(id)target previousAction:(SEL)previousAction nextAction:(SEL)nextAction doneAction:(SEL)doneAction titleText:(NSString*)titleText
{
IQBarButtonItemConfiguration *previousConfiguration = [[IQBarButtonItemConfiguration alloc] initWithImage:[UIImage keyboardPreviousImage] action:previousAction];
IQBarButtonItemConfiguration *nextConfiguration = [[IQBarButtonItemConfiguration alloc] initWithImage:[UIImage keyboardNextImage] action:nextAction];
IQBarButtonItemConfiguration *rightConfiguration = [[IQBarButtonItemConfiguration alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone action:doneAction];
[self addKeyboardToolbarWithTarget:target titleText:titleText rightBarButtonConfiguration:rightConfiguration previousBarButtonConfiguration:previousConfiguration nextBarButtonConfiguration:nextConfiguration];
}
- (void)addPreviousNextRightOnKeyboardWithTarget:(nullable id)target rightButtonImage:(nullable UIImage*)rightButtonImage previousAction:(nullable SEL)previousAction nextAction:(nullable SEL)nextAction rightButtonAction:(nullable SEL)rightButtonAction
{
[self addPreviousNextRightOnKeyboardWithTarget:target rightButtonImage:rightButtonImage previousAction:previousAction nextAction:nextAction rightButtonAction:rightButtonAction titleText:nil];
}
- (void)addPreviousNextRightOnKeyboardWithTarget:(nullable id)target rightButtonImage:(nullable UIImage*)rightButtonImage previousAction:(nullable SEL)previousAction nextAction:(nullable SEL)nextAction rightButtonAction:(nullable SEL)rightButtonAction shouldShowPlaceholder:(BOOL)shouldShowPlaceholder
{
[self addPreviousNextRightOnKeyboardWithTarget:target rightButtonImage:rightButtonImage previousAction:previousAction nextAction:nextAction rightButtonAction:rightButtonAction titleText:(shouldShowPlaceholder?[self drawingToolbarPlaceholder]:nil)];
}
- (void)addPreviousNextRightOnKeyboardWithTarget:(id)target rightButtonImage:(UIImage*)rightButtonImage previousAction:(SEL)previousAction nextAction:(SEL)nextAction rightButtonAction:(SEL)rightButtonAction titleText:(NSString*)titleText
{
IQBarButtonItemConfiguration *previousConfiguration = [[IQBarButtonItemConfiguration alloc] initWithImage:[UIImage keyboardPreviousImage] action:previousAction];
IQBarButtonItemConfiguration *nextConfiguration = [[IQBarButtonItemConfiguration alloc] initWithImage:[UIImage keyboardNextImage] action:nextAction];
IQBarButtonItemConfiguration *rightConfiguration = [[IQBarButtonItemConfiguration alloc] initWithImage:rightButtonImage action:rightButtonAction];
[self addKeyboardToolbarWithTarget:target titleText:titleText rightBarButtonConfiguration:rightConfiguration previousBarButtonConfiguration:previousConfiguration nextBarButtonConfiguration:nextConfiguration];
}
- (void)addPreviousNextRightOnKeyboardWithTarget:(id)target rightButtonTitle:(NSString*)rightButtonTitle previousAction:(SEL)previousAction nextAction:(SEL)nextAction rightButtonAction:(SEL)rightButtonAction
{
[self addPreviousNextRightOnKeyboardWithTarget:target rightButtonTitle:rightButtonTitle previousAction:previousAction nextAction:nextAction rightButtonAction:rightButtonAction titleText:nil];
}
- (void)addPreviousNextRightOnKeyboardWithTarget:(id)target rightButtonTitle:(NSString*)rightButtonTitle previousAction:(SEL)previousAction nextAction:(SEL)nextAction rightButtonAction:(SEL)rightButtonAction shouldShowPlaceholder:(BOOL)shouldShowPlaceholder
{
[self addPreviousNextRightOnKeyboardWithTarget:target rightButtonTitle:rightButtonTitle previousAction:previousAction nextAction:nextAction rightButtonAction:rightButtonAction titleText:(shouldShowPlaceholder?[self drawingToolbarPlaceholder]:nil)];
}
- (void)addPreviousNextRightOnKeyboardWithTarget:(id)target rightButtonTitle:(NSString*)rightButtonTitle previousAction:(SEL)previousAction nextAction:(SEL)nextAction rightButtonAction:(SEL)rightButtonAction titleText:(NSString*)titleText
{
IQBarButtonItemConfiguration *previousConfiguration = [[IQBarButtonItemConfiguration alloc] initWithImage:[UIImage keyboardPreviousImage] action:previousAction];
IQBarButtonItemConfiguration *nextConfiguration = [[IQBarButtonItemConfiguration alloc] initWithImage:[UIImage keyboardNextImage] action:nextAction];
IQBarButtonItemConfiguration *rightConfiguration = [[IQBarButtonItemConfiguration alloc] initWithTitle:rightButtonTitle action:rightButtonAction];
[self addKeyboardToolbarWithTarget:target titleText:titleText rightBarButtonConfiguration:rightConfiguration previousBarButtonConfiguration:previousConfiguration nextBarButtonConfiguration:nextConfiguration];
}
@end