diff --git a/docs/docs/topBar-buttons.md b/docs/docs/topBar-buttons.md index 1120a482321..56b7db18250 100644 --- a/docs/docs/topBar-buttons.md +++ b/docs/docs/topBar-buttons.md @@ -10,6 +10,7 @@ The following options can be used to customise buttons. name: 'example.CustomButtonComponent' }, text: 'Button one', + systemItem: 'done', // iOS only. Sets a system bar button item as the icon. Matches UIBarButtonSystemItem naming. See below for details. enabled: true, disableIconTint: false, color: 'red', @@ -18,6 +19,35 @@ The following options can be used to customise buttons. } ``` +## iOS System Items +On iOS, UIKit supplies some common bar button glyphs for developers to use. The following values can be supplied as values to to `systemItem` to use them as an icon for your button. + +* `done` +* `cancel` +* `edit` +* `save` +* `add` +* `flexibleSpace` +* `fixedSpace` +* `compose` +* `reply` +* `action` +* `organize` +* `bookmarks` +* `search` +* `refresh` +* `stop` +* `camera` +* `trash` +* `play` +* `pause` +* `rewind` +* `fastForward` +* `undo` +* `redo` + +More information about these glyphs can be found in [Apple's Human Interface Guidelines](https://developer.apple.com/ios/human-interface-guidelines/icons-and-images/system-icons/). + # Declaring Buttons statically Buttons can be defined in a screen's options: diff --git a/lib/ios/RCTConvert+UIBarButtonSystemItem.h b/lib/ios/RCTConvert+UIBarButtonSystemItem.h new file mode 100644 index 00000000000..b8b59c99a6f --- /dev/null +++ b/lib/ios/RCTConvert+UIBarButtonSystemItem.h @@ -0,0 +1,8 @@ +#import +#import + +@interface RCTConvert (UIBarButtonSystemItem) + ++ (UIBarButtonSystemItem)UIBarButtonSystemItem:(id)json; + +@end \ No newline at end of file diff --git a/lib/ios/RCTConvert+UIBarButtonSystemItem.m b/lib/ios/RCTConvert+UIBarButtonSystemItem.m new file mode 100644 index 00000000000..09de42ac9d5 --- /dev/null +++ b/lib/ios/RCTConvert+UIBarButtonSystemItem.m @@ -0,0 +1,32 @@ +#import +#import "RCTConvert+UIBarButtonSystemItem.h" + +@implementation RCTConvert (UIBarButtonSystemItem) + +RCT_ENUM_CONVERTER(UIBarButtonSystemItem, (@{ + @"done" : @(UIBarButtonSystemItemDone), + @"cancel" : @(UIBarButtonSystemItemCancel), + @"edit" : @(UIBarButtonSystemItemEdit), + @"save" : @(UIBarButtonSystemItemSave), + @"add" : @(UIBarButtonSystemItemAdd), + @"flexibleSpace" : @(UIBarButtonSystemItemFlexibleSpace), + @"fixedSpace" : @(UIBarButtonSystemItemFixedSpace), + @"compose" : @(UIBarButtonSystemItemCompose), + @"reply" : @(UIBarButtonSystemItemReply), + @"action" : @(UIBarButtonSystemItemAction), + @"organize" : @(UIBarButtonSystemItemOrganize), + @"bookmarks" : @(UIBarButtonSystemItemBookmarks), + @"search" : @(UIBarButtonSystemItemSearch), + @"refresh" : @(UIBarButtonSystemItemRefresh), + @"stop" : @(UIBarButtonSystemItemStop), + @"camera" : @(UIBarButtonSystemItemCamera), + @"trash" : @(UIBarButtonSystemItemTrash), + @"play" : @(UIBarButtonSystemItemPlay), + @"pause" : @(UIBarButtonSystemItemPause), + @"rewind" : @(UIBarButtonSystemItemRewind), + @"fastForward" : @(UIBarButtonSystemItemFastForward), + @"undo" : @(UIBarButtonSystemItemUndo), + @"redo" : @(UIBarButtonSystemItemRedo), +}), UIBarButtonSystemItemDone, integerValue) + +@end \ No newline at end of file diff --git a/lib/ios/RNNNavigationButtons.m b/lib/ios/RNNNavigationButtons.m index 3a1d8dd5a91..26e1822c054 100644 --- a/lib/ios/RNNNavigationButtons.m +++ b/lib/ios/RNNNavigationButtons.m @@ -67,6 +67,7 @@ -(RNNUIBarButtonItem*)buildButton: (NSDictionary*)dictionary defaultStyle:(RNNBu NSString* buttonId = dictionary[@"id"]; NSString* title = [self getValue:dictionary[@"text"] withDefault:[defaultStyle.text getWithDefaultValue:nil]]; NSDictionary* component = dictionary[@"component"]; + NSString* systemItemName = dictionary[@"systemItem"]; if (!buttonId) { @throw [NSException exceptionWithName:@"NSInvalidArgumentException" reason:[@"button id is not specified " stringByAppendingString:title] userInfo:nil]; @@ -91,6 +92,8 @@ -(RNNUIBarButtonItem*)buildButton: (NSDictionary*)dictionary defaultStyle:(RNNBu if (buttonTextAttributes.allKeys.count > 0) { [barButtonItem setTitleTextAttributes:buttonTextAttributes forState:UIControlStateNormal]; } + } else if (systemItemName) { + barButtonItem = [[RNNUIBarButtonItem alloc] init:buttonId withSystemItem:systemItemName]; } else { return nil; } diff --git a/lib/ios/RNNUIBarButtonItem.h b/lib/ios/RNNUIBarButtonItem.h index 9a765d1b244..40269a0aabc 100644 --- a/lib/ios/RNNUIBarButtonItem.h +++ b/lib/ios/RNNUIBarButtonItem.h @@ -9,6 +9,7 @@ -(instancetype)init:(NSString*)buttonId withIcon:(UIImage*)iconImage; -(instancetype)init:(NSString*)buttonId withTitle:(NSString*)title; -(instancetype)init:(NSString*)buttonId withCustomView:(RCTRootView*)reactView; +-(instancetype)init:(NSString*)buttonId withSystemItem:(NSString*)systemItemName; @end diff --git a/lib/ios/RNNUIBarButtonItem.m b/lib/ios/RNNUIBarButtonItem.m index eb2778e043d..1f13d68883b 100644 --- a/lib/ios/RNNUIBarButtonItem.m +++ b/lib/ios/RNNUIBarButtonItem.m @@ -1,6 +1,7 @@ #import #import #import "RNNUIBarButtonItem.h" +#import "RCTConvert+UIBarButtonSystemItem.h" @implementation RNNUIBarButtonItem @@ -25,6 +26,13 @@ -(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]; + self.buttonId = buttonId; + return self; +} - (void)rootViewDidChangeIntrinsicSize:(RCTRootView *)rootView { CGSize size = rootView.intrinsicContentSize; diff --git a/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj b/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj index ebe1de68908..8cd500ceeee 100644 --- a/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj +++ b/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj @@ -235,6 +235,8 @@ 50F5DFC21F407A8C001A00BC /* RNNTabBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = 50F5DFC01F407A8C001A00BC /* RNNTabBarController.m */; }; 50F5DFC51F407AA0001A00BC /* RNNNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 50F5DFC31F407AA0001A00BC /* RNNNavigationController.h */; }; 50F5DFC61F407AA0001A00BC /* RNNNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 50F5DFC41F407AA0001A00BC /* RNNNavigationController.m */; }; + 7365071121E4B16F004E020F /* RCTConvert+UIBarButtonSystemItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 7365070F21E4B16F004E020F /* RCTConvert+UIBarButtonSystemItem.h */; }; + 7365071221E4B16F004E020F /* RCTConvert+UIBarButtonSystemItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 7365071021E4B16F004E020F /* RCTConvert+UIBarButtonSystemItem.m */; }; 7B1126A01E2D263F00F9B03B /* RNNEventEmitter.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B11269F1E2D263F00F9B03B /* RNNEventEmitter.m */; }; 7B1126A31E2D2B6C00F9B03B /* RNNSplashScreen.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BA500761E254908001B9E1B /* RNNSplashScreen.h */; }; 7B1126A61E2D2B6C00F9B03B /* RNNBridgeModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BBFE5421E25330E002A6182 /* RNNBridgeModule.h */; }; @@ -558,6 +560,8 @@ 50F5DFC01F407A8C001A00BC /* RNNTabBarController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTabBarController.m; sourceTree = ""; }; 50F5DFC31F407AA0001A00BC /* RNNNavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNNavigationController.h; sourceTree = ""; }; 50F5DFC41F407AA0001A00BC /* RNNNavigationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNNavigationController.m; sourceTree = ""; }; + 7365070F21E4B16F004E020F /* RCTConvert+UIBarButtonSystemItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+UIBarButtonSystemItem.h"; sourceTree = ""; }; + 7365071021E4B16F004E020F /* RCTConvert+UIBarButtonSystemItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+UIBarButtonSystemItem.m"; sourceTree = ""; }; 7B11269E1E2D263F00F9B03B /* RNNEventEmitter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNNEventEmitter.h; sourceTree = ""; }; 7B11269F1E2D263F00F9B03B /* RNNEventEmitter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNEventEmitter.m; sourceTree = ""; }; 7B4928061E70415400555040 /* RNNCommandsHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNNCommandsHandler.h; sourceTree = ""; }; @@ -693,6 +697,8 @@ 5038A3C0216E1E66009280BC /* RNNFontAttributesCreator.m */, 505EDD48214FDA800071C7DE /* RCTConvert+Modal.h */, 50E02BD521A6E54B00A43942 /* RCTConvert+SideMenuOpenGestureMode.h */, + 7365070F21E4B16F004E020F /* RCTConvert+UIBarButtonSystemItem.h */, + 7365071021E4B16F004E020F /* RCTConvert+UIBarButtonSystemItem.m */, 5038A3BB216E1490009280BC /* RNNTabBarItemCreator.h */, 5038A3BC216E1490009280BC /* RNNTabBarItemCreator.m */, 5053CE7D2175FB1900D0386B /* RNNDefaultOptionsHelper.h */, @@ -1186,6 +1192,7 @@ 50495942216F5E5D006D2B81 /* NullBool.h in Headers */, 263905AE1E4C6F440023D7D3 /* MMDrawerBarButtonItem.h in Headers */, 5012241621736667000F5F98 /* Color.h in Headers */, + 7365071121E4B16F004E020F /* RCTConvert+UIBarButtonSystemItem.h in Headers */, 5064495D20DC62B90026709C /* RNNSideMenuSideOptions.h in Headers */, 50F5DFC11F407A8C001A00BC /* RNNTabBarController.h in Headers */, 50395587217480C900B0A663 /* IntNumber.h in Headers */, @@ -1418,6 +1425,7 @@ 263905B41E4C6F440023D7D3 /* MMDrawerVisualState.m in Sources */, 5012240B21735959000F5F98 /* RNNSideMenuPresenter.m in Sources */, 502CB46F20CD1DDA0019B2FE /* RNNBackButtonOptions.m in Sources */, + 7365071221E4B16F004E020F /* RCTConvert+UIBarButtonSystemItem.m in Sources */, 5012241B21736678000F5F98 /* Image.m in Sources */, 50495943216F5E5D006D2B81 /* NullBool.m in Sources */, 5038A3C7216E2D93009280BC /* Number.m in Sources */, diff --git a/lib/src/interfaces/Options.ts b/lib/src/interfaces/Options.ts index 724cd595883..d05c8ceab4a 100644 --- a/lib/src/interfaces/Options.ts +++ b/lib/src/interfaces/Options.ts @@ -5,6 +5,7 @@ type Color = string; type FontFamily = string; type LayoutOrientation = 'portrait' | 'landscape'; type AndroidDensityNumber = number; +type SystemItemIcon = 'done' | 'cancel' | 'edit' | 'save' | 'add' | 'flexibleSpace' | 'fixedSpace' | 'compose' | 'reply' | 'action' | 'organize' | 'bookmarks' | 'search' | 'refresh' | 'stop' | 'camera' | 'trash' | 'play' | 'pause' | 'rewind' | 'fastForward' | 'undo' | 'redo'; export interface OptionsSplitView { /** @@ -256,6 +257,10 @@ export interface OptionsTopBarButton { */ passProps?: object; }; + /** + * (iOS only) Set the button as an iOS system icon + */ + systemItem?: SystemItemIcon; /** * Set the button text */