Skip to content

Commit

Permalink
Add Icon insets support for buttons (#4699)
Browse files Browse the repository at this point in the history
* Add button.iconInsets

* Define iconInsets in Options.ts

* Apply color on button iconImage
  • Loading branch information
yogevbd authored Feb 7, 2019
1 parent b3b88d1 commit 545e5fe
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 9 deletions.
2 changes: 2 additions & 0 deletions lib/ios/RNNButtonOptions.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#import "RNNOptions.h"
#import "RNNInsetsOptions.h"

@interface RNNButtonOptions : RNNOptions

Expand All @@ -9,5 +10,6 @@
@property (nonatomic, strong) Color* disabledColor;
@property (nonatomic, strong) Image* icon;
@property (nonatomic, strong) Bool* enabled;
@property (nonatomic, strong) RNNInsetsOptions* iconInsets;

@end
1 change: 1 addition & 0 deletions lib/ios/RNNButtonOptions.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ - (instancetype)initWithDict:(NSDictionary *)dict {
self.color = [ColorParser parse:dict key:@"color"];
self.disabledColor = [ColorParser parse:dict key:@"disabledColor"];
self.icon = [ImageParser parse:dict key:@"icon"];
self.iconInsets = [[RNNInsetsOptions alloc] initWithDict:dict];
self.enabled = [BoolParser parse:dict key:@"enabled"];


Expand Down
10 changes: 10 additions & 0 deletions lib/ios/RNNInsetsOptions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#import "RNNOptions.h"

@interface RNNInsetsOptions : RNNOptions

@property (nonatomic, strong) Double* top;
@property (nonatomic, strong) Double* left;
@property (nonatomic, strong) Double* right;
@property (nonatomic, strong) Double* bottom;

@end
16 changes: 16 additions & 0 deletions lib/ios/RNNInsetsOptions.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#import "RNNInsetsOptions.h"

@implementation RNNInsetsOptions

- (instancetype)initWithDict:(NSDictionary *)dict {
self = [super init];

self.top = [DoubleParser parse:dict key:@"top"];
self.left = [DoubleParser parse:dict key:@"left"];
self.bottom = [DoubleParser parse:dict key:@"bottom"];
self.right = [DoubleParser parse:dict key:@"right"];

return self;
}

@end
38 changes: 31 additions & 7 deletions lib/ios/RNNNavigationButtons.m
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#import "RCTHelpers.h"
#import "UIImage+tint.h"
#import "RNNRootViewController.h"
#import "UIImage+insets.h"

@interface RNNNavigationButtons()

Expand All @@ -28,19 +29,19 @@ - (void)applyLeftButtons:(NSArray *)leftButtons rightButtons:(NSArray *)rightBut
_defaultLeftButtonStyle = defaultLeftButtonStyle;
_defaultRightButtonStyle = defaultRightButtonStyle;
if (leftButtons) {
[self setButtons:leftButtons side:@"left" animated:NO defaultStyle:_defaultLeftButtonStyle];
[self setButtons:leftButtons side:@"left" animated:NO defaultStyle:_defaultLeftButtonStyle insets:[self leftButtonInsets:_defaultLeftButtonStyle.iconInsets]];
}

if (rightButtons) {
[self setButtons:rightButtons side:@"right" animated:NO defaultStyle:_defaultRightButtonStyle];
[self setButtons:rightButtons side:@"right" animated:NO defaultStyle:_defaultRightButtonStyle insets:[self rightButtonInsets:_defaultRightButtonStyle.iconInsets]];
}
}

-(void)setButtons:(NSArray*)buttons side:(NSString*)side animated:(BOOL)animated defaultStyle:(RNNButtonOptions *)defaultStyle {
-(void)setButtons:(NSArray*)buttons side:(NSString*)side animated:(BOOL)animated defaultStyle:(RNNButtonOptions *)defaultStyle insets:(UIEdgeInsets)insets {
NSMutableArray *barButtonItems = [NSMutableArray new];
NSArray* resolvedButtons = [self resolveButtons:buttons];
for (NSDictionary *button in resolvedButtons) {
RNNUIBarButtonItem* barButtonItem = [self buildButton:button defaultStyle:defaultStyle];
RNNUIBarButtonItem* barButtonItem = [self buildButton:button defaultStyle:defaultStyle insets:insets];
if(barButtonItem) {
[barButtonItems addObject:barButtonItem];
}
Expand All @@ -67,12 +68,15 @@ - (NSArray *)resolveButtons:(id)buttons {
}
}

-(RNNUIBarButtonItem*)buildButton: (NSDictionary*)dictionary defaultStyle:(RNNButtonOptions *)defaultStyle {
-(RNNUIBarButtonItem*)buildButton: (NSDictionary*)dictionary defaultStyle:(RNNButtonOptions *)defaultStyle insets:(UIEdgeInsets)insets {
NSString* buttonId = dictionary[@"id"];
NSString* title = [self getValue:dictionary[@"text"] withDefault:[defaultStyle.text getWithDefaultValue:nil]];
NSDictionary* component = dictionary[@"component"];
NSString* systemItemName = dictionary[@"systemItem"];

UIColor* color = [self color:[RCTConvert UIColor:dictionary[@"color"]] defaultColor:[defaultStyle.color getWithDefaultValue:nil]];
UIColor* disabledColor = [self color:[RCTConvert UIColor:dictionary[@"disabledColor"]] defaultColor:[defaultStyle.disabledColor getWithDefaultValue:nil]];

if (!buttonId) {
@throw [NSException exceptionWithName:@"NSInvalidArgumentException" reason:[@"button id is not specified " stringByAppendingString:title] userInfo:nil];
}
Expand All @@ -83,6 +87,14 @@ -(RNNUIBarButtonItem*)buildButton: (NSDictionary*)dictionary defaultStyle:(RNNBu
iconImage = [RCTConvert UIImage:iconImage];
}

if (iconImage) {
iconImage = [iconImage imageWithInsets:insets];
if (color) {
iconImage = [iconImage withTintColor:color];
}
}


RNNUIBarButtonItem *barButtonItem;
if (component) {
RNNComponentOptions* componentOptions = [RNNComponentOptions new];
Expand Down Expand Up @@ -116,8 +128,6 @@ -(RNNUIBarButtonItem*)buildButton: (NSDictionary*)dictionary defaultStyle:(RNNBu
NSMutableDictionary* textAttributes = [[NSMutableDictionary alloc] init];
NSMutableDictionary* disabledTextAttributes = [[NSMutableDictionary alloc] init];

UIColor* color = [self color:[RCTConvert UIColor:dictionary[@"color"]] defaultColor:[defaultStyle.color getWithDefaultValue:nil]];
UIColor* disabledColor = [self color:[RCTConvert UIColor:dictionary[@"disabledColor"]] defaultColor:[defaultStyle.disabledColor getWithDefaultValue:nil]];
if (!enabledBool && disabledColor) {
color = disabledColor;
[disabledTextAttributes setObject:disabledColor forKey:NSForegroundColorAttributeName];
Expand Down Expand Up @@ -185,4 +195,18 @@ - (id)getValue:(id)value withDefault:(id)defaultValue {
return value ? value : defaultValue;
}

- (UIEdgeInsets)leftButtonInsets:(RNNInsetsOptions *)defaultInsets {
return UIEdgeInsetsMake([defaultInsets.top getWithDefaultValue:0],
[defaultInsets.left getWithDefaultValue:0],
[defaultInsets.bottom getWithDefaultValue:0],
[defaultInsets.right getWithDefaultValue:15]);
}

- (UIEdgeInsets)rightButtonInsets:(RNNInsetsOptions *)defaultInsets {
return UIEdgeInsetsMake([defaultInsets.top getWithDefaultValue:0],
[defaultInsets.left getWithDefaultValue:15],
[defaultInsets.bottom getWithDefaultValue:0],
[defaultInsets.right getWithDefaultValue:0]);
}

@end
13 changes: 11 additions & 2 deletions lib/ios/RNNUIBarButtonItem.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
@implementation RNNUIBarButtonItem

-(instancetype)init:(NSString*)buttonId withIcon:(UIImage*)iconImage {
self = [super initWithImage:iconImage style:UIBarButtonItemStylePlain target:nil action:nil];
UIButton* button = [[UIButton alloc] init];
[button addTarget:self action:@selector(onButtonPressed) forControlEvents:UIControlEventTouchUpInside];
[button setImage:iconImage forState:UIControlStateNormal];
self = [super initWithCustomView:button];
self.buttonId = buttonId;
return self;
}
Expand All @@ -26,7 +29,7 @@ -(instancetype)init:(NSString*)buttonId withCustomView:(RCTRootView *)reactView
self.buttonId = buttonId;
return self;
}

-(instancetype)init:(NSString*)buttonId withSystemItem:(NSString *)systemItemName {
UIBarButtonSystemItem systemItem = [RCTConvert UIBarButtonSystemItem:systemItemName];
self = [super initWithBarButtonSystemItem:systemItem target:nil action:nil];
Expand All @@ -40,4 +43,10 @@ - (void)rootViewDidChangeIntrinsicSize:(RCTRootView *)rootView {
self.width = size.width;
}

- (void)onButtonPressed {
[self.target performSelector:self.action
withObject:self
afterDelay:0];
}

@end
16 changes: 16 additions & 0 deletions lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@
505EDD4A214FDA800071C7DE /* RCTConvert+Modal.h in Headers */ = {isa = PBXBuildFile; fileRef = 505EDD48214FDA800071C7DE /* RCTConvert+Modal.h */; };
5060DE73219DAD7E00D0C052 /* ReactNativeNavigation.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BA500731E2544B9001B9E1B /* ReactNativeNavigation.h */; };
5060DE74219DAD8300D0C052 /* RNNBridgeManagerDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 502CB43920CBCA140019B2FE /* RNNBridgeManagerDelegate.h */; };
506317AA220B547400B26FC3 /* UIImage+insets.h in Headers */ = {isa = PBXBuildFile; fileRef = 506317A8220B547400B26FC3 /* UIImage+insets.h */; };
506317AB220B547400B26FC3 /* UIImage+insets.m in Sources */ = {isa = PBXBuildFile; fileRef = 506317A9220B547400B26FC3 /* UIImage+insets.m */; };
506317AE220B550600B26FC3 /* RNNInsetsOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 506317AC220B550600B26FC3 /* RNNInsetsOptions.h */; };
506317AF220B550600B26FC3 /* RNNInsetsOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 506317AD220B550600B26FC3 /* RNNInsetsOptions.m */; };
5064495D20DC62B90026709C /* RNNSideMenuSideOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 5064495B20DC62B90026709C /* RNNSideMenuSideOptions.h */; };
5064495E20DC62B90026709C /* RNNSideMenuSideOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 5064495C20DC62B90026709C /* RNNSideMenuSideOptions.m */; };
50644A2020E11A720026709C /* Constants.h in Headers */ = {isa = PBXBuildFile; fileRef = 50644A1E20E11A720026709C /* Constants.h */; };
Expand Down Expand Up @@ -508,6 +512,10 @@
505EDD3B214FA8000071C7DE /* RNNViewControllerPresenter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNViewControllerPresenter.m; sourceTree = "<group>"; };
505EDD47214FC4A60071C7DE /* RNNLayoutProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNLayoutProtocol.h; sourceTree = "<group>"; };
505EDD48214FDA800071C7DE /* RCTConvert+Modal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+Modal.h"; sourceTree = "<group>"; };
506317A8220B547400B26FC3 /* UIImage+insets.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIImage+insets.h"; sourceTree = "<group>"; };
506317A9220B547400B26FC3 /* UIImage+insets.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIImage+insets.m"; sourceTree = "<group>"; };
506317AC220B550600B26FC3 /* RNNInsetsOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNInsetsOptions.h; sourceTree = "<group>"; };
506317AD220B550600B26FC3 /* RNNInsetsOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNInsetsOptions.m; sourceTree = "<group>"; };
5064495B20DC62B90026709C /* RNNSideMenuSideOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNSideMenuSideOptions.h; sourceTree = "<group>"; };
5064495C20DC62B90026709C /* RNNSideMenuSideOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNSideMenuSideOptions.m; sourceTree = "<group>"; };
50644A1E20E11A720026709C /* Constants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Constants.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -697,6 +705,8 @@
50644A1F20E11A720026709C /* Constants.m */,
50706E6B20CE7CA5003345C3 /* UIImage+tint.h */,
50706E6C20CE7CA5003345C3 /* UIImage+tint.m */,
506317A8220B547400B26FC3 /* UIImage+insets.h */,
506317A9220B547400B26FC3 /* UIImage+insets.m */,
5038A372216CDDB6009280BC /* UIViewController+SideMenuController.h */,
5038A373216CDDB6009280BC /* UIViewController+SideMenuController.m */,
5038A3BF216E1E66009280BC /* RNNFontAttributesCreator.h */,
Expand Down Expand Up @@ -931,6 +941,8 @@
E33AC20720B5C4F90090DB8A /* RNNSplitViewOptions.m */,
E3458D3C20BD9CA10023149B /* RNNPreviewOptions.h */,
E3458D3D20BD9CE40023149B /* RNNPreviewOptions.m */,
506317AC220B550600B26FC3 /* RNNInsetsOptions.h */,
506317AD220B550600B26FC3 /* RNNInsetsOptions.m */,
);
name = Options;
sourceTree = "<group>";
Expand Down Expand Up @@ -1250,6 +1262,7 @@
50D031342005149000386B3D /* RNNOverlayManager.h in Headers */,
7B1126A71E2D2B6C00F9B03B /* RNNEventEmitter.h in Headers */,
E8A430111F9CB87B00B61A20 /* RNNAnimatedView.h in Headers */,
506317AA220B547400B26FC3 /* UIImage+insets.h in Headers */,
5038A3C6216E2D93009280BC /* Number.h in Headers */,
50887C1520ECC5C200D06111 /* RNNButtonOptions.h in Headers */,
5049593E216F5D73006D2B81 /* BoolParser.h in Headers */,
Expand Down Expand Up @@ -1299,6 +1312,7 @@
507F43C91FF4F9CC00D9425B /* RNNTopTabOptions.h in Headers */,
E8A5CD521F464F0400E89D0D /* RNNAnimator.h in Headers */,
50451D0D2042F70900695F00 /* RNNTransition.h in Headers */,
506317AE220B550600B26FC3 /* RNNInsetsOptions.h in Headers */,
507F43F81FF525B500D9425B /* RNNSegmentedControl.h in Headers */,
50175CD1207A2AA1004FE91B /* RNNComponentOptions.h in Headers */,
5038A3B1216DF41B009280BC /* UIViewController+RNNOptions.h in Headers */,
Expand Down Expand Up @@ -1481,6 +1495,7 @@
506A2B1520973DFD00F43A95 /* RNNErrorHandler.m in Sources */,
50395588217480C900B0A663 /* IntNumber.m in Sources */,
7BBFE5441E25330E002A6182 /* RNNBridgeModule.m in Sources */,
506317AF220B550600B26FC3 /* RNNInsetsOptions.m in Sources */,
261F0E651E6EC94900989DE2 /* RNNModalManager.m in Sources */,
50395590217482FE00B0A663 /* NullIntNumber.m in Sources */,
E8A5CD631F49114F00E89D0D /* RNNElement.m in Sources */,
Expand Down Expand Up @@ -1519,6 +1534,7 @@
E33AC20020B5BA0B0090DB8A /* RNNSplitViewController.m in Sources */,
263905CF1E4C6F440023D7D3 /* TheSidebarController.m in Sources */,
5038A3C2216E1E66009280BC /* RNNFontAttributesCreator.m in Sources */,
506317AB220B547400B26FC3 /* UIImage+insets.m in Sources */,
E8A430121F9CB87B00B61A20 /* RNNAnimatedView.m in Sources */,
507F43F51FF4FCFE00D9425B /* HMSegmentedControl.m in Sources */,
5012242321736883000F5F98 /* NullColor.m in Sources */,
Expand Down
7 changes: 7 additions & 0 deletions lib/ios/UIImage+insets.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#import <UIKit/UIKit.h>

@interface UIImage (insets)

- (UIImage *)imageWithInsets:(UIEdgeInsets)insets;

@end
20 changes: 20 additions & 0 deletions lib/ios/UIImage+insets.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#import "UIImage+insets.h"

@implementation UIImage (insets)

- (UIImage *)imageWithInsets:(UIEdgeInsets)insets {
UIGraphicsBeginImageContextWithOptions(CGSizeMake(self.size.width + insets.left + insets.right,
self.size.height + insets.top + insets.bottom), false, self.scale);
CGContextRef context = UIGraphicsGetCurrentContext();
UIGraphicsPushContext(context);

CGPoint origin = CGPointMake(insets.left, insets.top);
[self drawAtPoint:origin];

UIGraphicsPopContext();
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}

@end
23 changes: 23 additions & 0 deletions lib/src/interfaces/Options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,10 @@ export interface OptionsTopBarButton {
* Set the button icon
*/
icon?: ImageRequireSource;
/**
* Set the button icon insets
*/
iconInsets?: IconInsets;
/**
* Set the button as a custom component
*/
Expand Down Expand Up @@ -692,6 +696,25 @@ export interface OptionsAnimationProperties {
rotation?: OptionsAnimationPropertyConfig;
}

export interface IconInsets {
/**
* Configure top inset
*/
top?: number;
/**
* Configure left inset
*/
left?: number;
/**
* Configure bottom inset
*/
bottom?: number;
/**
* Configure right inset
*/
right?: number;
}

export interface OptionsAnimationPropertiesId extends OptionsAnimationProperties {
/**
* ID of the Top Bar we want to animate
Expand Down

0 comments on commit 545e5fe

Please sign in to comment.