// // 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 #import @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 *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]; } return _fixedSpaceBarButton; } -(CGSize)sizeThatFits:(CGSize)size { CGSize sizeThatFit = [super sizeThatFits:size]; sizeThatFit.height = 44; return sizeThatFit; } -(void)setBarStyle:(UIBarStyle)barStyle { [super setBarStyle:barStyle]; if (barStyle == UIBarStyleDefault) { [self.titleBarButton setSelectableTextColor:[UIColor colorWithRed:0.0 green:0.5 blue:1.0 alpha:1.0]]; } else { [self.titleBarButton setSelectableTextColor:[UIColor yellowColor]]; } } -(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 *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