├── Screenshots ├── screenshot-1.png ├── screenshot-2.png ├── screenshot-3.png ├── screenshot-4.png ├── screenshot-5.png └── screenshot-6.png ├── ButtonItemSample ├── ButtonItemSample │ ├── Default.png │ ├── Default@2x.png │ ├── Default-568h@2x.png │ ├── SampleAppDelegate.h │ ├── main.m │ ├── ButtonItemSample-Prefix.pch │ ├── SampleViewController.h │ ├── ButtonItemSample-Info.plist │ ├── SampleViewController.m │ ├── SampleAppDelegate.m │ └── MainStoryboard.storyboard └── ButtonItemSample.xcodeproj │ ├── project.xcworkspace │ └── contents.xcworkspacedata │ └── project.pbxproj ├── LICENSE ├── BPBarButtonItem.podspec ├── BPBarButtonItem ├── BPBarButtonItem.h └── BPBarButtonItem.m └── README.md /Screenshots/screenshot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitSuites/BPBarButtonItem/HEAD/Screenshots/screenshot-1.png -------------------------------------------------------------------------------- /Screenshots/screenshot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitSuites/BPBarButtonItem/HEAD/Screenshots/screenshot-2.png -------------------------------------------------------------------------------- /Screenshots/screenshot-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitSuites/BPBarButtonItem/HEAD/Screenshots/screenshot-3.png -------------------------------------------------------------------------------- /Screenshots/screenshot-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitSuites/BPBarButtonItem/HEAD/Screenshots/screenshot-4.png -------------------------------------------------------------------------------- /Screenshots/screenshot-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitSuites/BPBarButtonItem/HEAD/Screenshots/screenshot-5.png -------------------------------------------------------------------------------- /Screenshots/screenshot-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitSuites/BPBarButtonItem/HEAD/Screenshots/screenshot-6.png -------------------------------------------------------------------------------- /ButtonItemSample/ButtonItemSample/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitSuites/BPBarButtonItem/HEAD/ButtonItemSample/ButtonItemSample/Default.png -------------------------------------------------------------------------------- /ButtonItemSample/ButtonItemSample/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitSuites/BPBarButtonItem/HEAD/ButtonItemSample/ButtonItemSample/Default@2x.png -------------------------------------------------------------------------------- /ButtonItemSample/ButtonItemSample/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BitSuites/BPBarButtonItem/HEAD/ButtonItemSample/ButtonItemSample/Default-568h@2x.png -------------------------------------------------------------------------------- /ButtonItemSample/ButtonItemSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ButtonItemSample/ButtonItemSample/SampleAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SampleAppDelegate.h 3 | // ButtonItemSample 4 | // 5 | // Created by Cory Imdieke on 4/25/13. 6 | // Copyright (c) 2013 BitSuites, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface SampleAppDelegate : UIResponder 13 | 14 | @property (strong, nonatomic) UIWindow *window; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /ButtonItemSample/ButtonItemSample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ButtonItemSample 4 | // 5 | // Created by Cory Imdieke on 4/25/13. 6 | // Copyright (c) 2013 BitSuites, LLC. All rights reserved. 7 | // 8 | 9 | #import "SampleAppDelegate.h" 10 | 11 | 12 | int main (int argc, char *argv[]){ 13 | @autoreleasepool{ 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([SampleAppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ButtonItemSample/ButtonItemSample/ButtonItemSample-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'ButtonItemSample' target in the 'ButtonItemSample' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_5_0 8 | #warning "This project uses features only available in iOS SDK 5.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /ButtonItemSample/ButtonItemSample/SampleViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SampleViewController.h 3 | // ButtonItemSample 4 | // 5 | // Created by Cory Imdieke on 4/25/13. 6 | // Copyright (c) 2013 BitSuites, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "BPBarButtonItem.h" 11 | 12 | 13 | @interface SampleViewController : UIViewController 14 | 15 | @property (nonatomic, assign) BPBarButtonItemStyle buttonStyle; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Cory Imdieke 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /BPBarButtonItem.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "BPBarButtonItem" 3 | s.version = "0.0.3" 4 | s.summary = "A tool for making awesome looking custom UIBarButtonItems on the fly." 5 | s.description = "BPBarButtonItem is a tool for making awesome looking custom UIBarButtonItems on the fly. BPBarButtonItem is **NOT** a subclass of `UIBarButtonItem` but an `NSObject` which creates skinned plain `UIBarButtonItem`s for use however you want. BPBarButtonItem can also be used to skin `UIBarButtonItem`s which have already been created, like in a nib or Storyboard. Generated buttons have support for both orientation styles." 6 | s.homepage = "https://github.com/BitSuites/BPBarButtonItem" 7 | s.screenshots = "https://raw.github.com/BitSuites/BPBarButtonItem/master/Screenshots/screenshot-1.png", "https://raw.github.com/BitSuites/BPBarButtonItem/master/Screenshots/screenshot-3.png" 8 | s.license = 'MIT' 9 | s.author = { "Cory Imdieke" => "coryi@bitsuites.com" } 10 | s.source = { :git => "https://github.com/BitSuites/BPBarButtonItem.git", :tag => "0.0.3" } 11 | s.platform = :ios, '5.0' 12 | s.source_files = 'BPBarButtonItem' 13 | s.requires_arc = true 14 | end 15 | -------------------------------------------------------------------------------- /BPBarButtonItem/BPBarButtonItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // BPBarButtonItem.h 3 | // 4 | // Created by Cory Imdieke on 4/25/13. 5 | // Copyright (c) 2013 BitSuites, LLC. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | 11 | typedef enum : NSInteger { 12 | BPBarButtonItemStyleAction, 13 | BPBarButtonItemStyleStandardDark, 14 | BPBarButtonItemStyleStandardLight 15 | } BPBarButtonItemStyle; 16 | 17 | @interface BPBarButtonItem : NSObject 18 | 19 | // Generate individual buttons 20 | + (id)barButtonItemWithStyle:(BPBarButtonItemStyle)style title:(NSString *)title target:(id)target action:(SEL)action; 21 | + (id)barButtonItemWithTintColor:(UIColor *)tintColor title:(NSString *)title target:(id)target action:(SEL)action; 22 | 23 | // Skin all or specific bar button items 24 | + (void)customizeBarButtonItem:(UIBarButtonItem *)item withStyle:(BPBarButtonItemStyle)style; 25 | + (void)customizeBarButtonItem:(UIBarButtonItem *)item withTintColor:(UIColor *)tintColor; 26 | 27 | // Skin all or specific segmented controls 28 | + (void)customizeSegmentedControl:(UISegmentedControl *)segmentedControl withStyle:(BPBarButtonItemStyle)style; 29 | + (void)customizeSegmentedControl:(UISegmentedControl *)segmentedControl withTintColor:(UIColor *)tintColor; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /ButtonItemSample/ButtonItemSample/ButtonItemSample-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.mobilevisionsoftware.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIMainStoryboardFile 28 | MainStoryboard 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /ButtonItemSample/ButtonItemSample/SampleViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SampleViewController.m 3 | // ButtonItemSample 4 | // 5 | // Created by Cory Imdieke on 4/25/13. 6 | // Copyright (c) 2013 BitSuites, LLC. All rights reserved. 7 | // 8 | 9 | #import "SampleViewController.h" 10 | 11 | 12 | @interface SampleViewController () 13 | 14 | @end 15 | 16 | @implementation SampleViewController 17 | 18 | - (id)initWithCoder:(NSCoder *)aDecoder{ 19 | self = [super initWithCoder:aDecoder]; 20 | if(self){ 21 | // Default style 22 | _buttonStyle = BPBarButtonItemStyleStandardDark; 23 | } 24 | return self; 25 | } 26 | 27 | - (void)viewDidLoad{ 28 | [super viewDidLoad]; 29 | // Do any additional setup after loading the view, typically from a nib. 30 | 31 | if(self.buttonStyle == BPBarButtonItemStyleStandardDark) 32 | self.navigationController.navigationBar.tintColor = [UIColor blackColor]; 33 | 34 | // These override the appearance proxy settings we have in the delegate 35 | self.navigationItem.rightBarButtonItem = [BPBarButtonItem barButtonItemWithStyle:BPBarButtonItemStyleAction title:@"Action" target:self action:@selector(switchStyles)]; 36 | self.navigationItem.leftBarButtonItem = [BPBarButtonItem barButtonItemWithStyle:self.buttonStyle title:@"Standard" target:self action:@selector(switchStyles)]; 37 | 38 | [BPBarButtonItem customizeSegmentedControl:(UISegmentedControl *)[self.navigationItem titleView] withStyle:self.buttonStyle]; 39 | } 40 | 41 | - (void)didReceiveMemoryWarning{ 42 | [super didReceiveMemoryWarning]; 43 | // Dispose of any resources that can be recreated. 44 | } 45 | 46 | - (void)switchStyles{ 47 | if(self.buttonStyle == BPBarButtonItemStyleStandardDark){ 48 | // Switch to Light 49 | UINavigationController *sample = [self.storyboard instantiateInitialViewController]; 50 | [(SampleViewController *)[sample topViewController] setButtonStyle:BPBarButtonItemStyleStandardLight]; 51 | [self presentViewController:sample animated:YES completion:nil]; 52 | } else { 53 | // Switch back to Dark 54 | [self dismissViewControllerAnimated:YES completion:nil]; 55 | } 56 | } 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /ButtonItemSample/ButtonItemSample/SampleAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // SampleAppDelegate.m 3 | // ButtonItemSample 4 | // 5 | // Created by Cory Imdieke on 4/25/13. 6 | // Copyright (c) 2013 BitSuites, LLC. All rights reserved. 7 | // 8 | 9 | #import "SampleAppDelegate.h" 10 | #import "BPBarButtonItem.h" 11 | 12 | 13 | @implementation SampleAppDelegate 14 | 15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ 16 | // Override point for customization after application launch. 17 | 18 | // This sets the appearance proxy which ultimately sets the back button in the second test controller 19 | [BPBarButtonItem customizeBarButtonItem:nil withStyle:BPBarButtonItemStyleStandardDark]; 20 | 21 | return YES; 22 | } 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application{ 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 27 | } 28 | 29 | - (void)applicationDidEnterBackground:(UIApplication *)application{ 30 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 31 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 32 | } 33 | 34 | - (void)applicationWillEnterForeground:(UIApplication *)application{ 35 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 36 | } 37 | 38 | - (void)applicationDidBecomeActive:(UIApplication *)application{ 39 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 40 | } 41 | 42 | - (void)applicationWillTerminate:(UIApplication *)application{ 43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /ButtonItemSample/ButtonItemSample/MainStoryboard.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DEPRECATED BPBarButtonItem 2 | =============== 3 | 4 | NOTE - This code has been deperecated since it isn't applicable to apps built for iOS 7 and after. 5 | 6 | BPBarButtonItem is a tool for making awesome looking custom UIBarButtonItems on the fly. BPBarButtonItem is *NOT* a subclass of `UIBarButtonItem` but an `NSObject` which creates skinned plain `UIBarButtonItem`s for use however you want. BPBarButtonItem can also be used to skin `UIBarButtonItem`s which have already been created, like in a nib or Storyboard. Generated buttons have support for both orientation styles, and automatically show up properly for back buttons. 7 | 8 | ![BPBarButtonItem Screenshot 1][sshot1]
9 |
10 | ![BPBarButtonItem Screenshot 2][sshot2]
11 |
12 | ![BPBarButtonItem Screenshot 3][sshot3]
13 |
14 | ![BPBarButtonItem Screenshot 4][sshot4]
15 |
16 | ![BPBarButtonItem Screenshot 5][sshot5]
17 |
18 | ![BPBarButtonItem Screenshot 6][sshot6]
19 | 20 | ## Installation 21 | 22 | ### From [CocoaPods](http://cocoapods.org/?q=bpbarbuttonitem) 23 | 24 | pod 'BPBarButtonItem' 25 | 26 | ### From Source 27 | 28 | * Drag the `BPBarButtonItem/` folder to your project (make sure you copy all files/folders) 29 | * `#import "BPBarButtonItem.h"` 30 | 31 | ## How to Use 32 | 33 | There are 3 main ways to use BPBarButtonItem: 34 | 35 | ### Creating a brand new button in code 36 | 37 | This will allow you to create a brand new `UIBarButtonItem` on the fly. You can use any of the predefined styles or set your own tint color. 38 | 39 | ````objective-c 40 | self.navigationItem.rightBarButtonItem = [BPBarButtonItem barButtonItemWithStyle:BPBarButtonItemStyleAction title:@"Action" target:self action:@selector(buttonAction:)]; 41 | ```` 42 | ```objective-c 43 | self.navigationItem.rightBarButtonItem = [BPBarButtonItem barButtonItemWithTintColor:[UIColor redColor] title:@"Red" target:self action:@selector(buttonAction:)]; 44 | ``` 45 | 46 | ### Styling an existing button (often from a nib or Storyboard) 47 | 48 | This will style any existing `UIBarButtonItem`. The title, action, and any other attributes are not modified. This works from an `IBOutlet` or by accessing the `navigationItem`'s right and left button properties directly. 49 | 50 | ```objective-c 51 | [BPBarButtonItem customizeBarButtonItem:self.navigationItem.rightBarButtonItem withStyle:BPBarButtonItemStyleStandardDark]; 52 | ``` 53 | ```objective-c 54 | [BPBarButtonItem customizeBarButtonItem:self.navigationItem.rightBarButtonItem withTintColor:[UIColor colorWithRed:0.048 green:0.169 blue:0.458 alpha:1.000]]; 55 | ``` 56 | 57 | ### Styling ALL the buttons using an Appearance Proxy 58 | 59 | Want to style all the buttons in your app to be consistent, but don't want to set them all individually? Setting the default button style is almost identical to styling an existing button, except you pass in `nil` for the button item. You'll generally want to do this as part of your `application:didFinishLaunchingWithOptions:` method. 60 | 61 | ```objective-c 62 | [BPBarButtonItem customizeBarButtonItem:nil withStyle:BPBarButtonItemStyleStandardDark]; 63 | ``` 64 | 65 | Note that with the Appearance Proxy method, you can still override individual buttons using the existing button styling method above. 66 | 67 | You can also get complex and pass in a specific Appearance Proxy as well. For example, this may be used to stylize buttons in a `UINavigationBar` but not those in a `UIToolbar`. 68 | 69 | ```objective-c 70 | [BPBarButtonItem customizeBarButtonItem:[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] withStyle:BPBarButtonItemStyleStandardLight]; 71 | ``` 72 | 73 | ### Styling Segmented Controls 74 | 75 | You can style a `UISegmentedControl` directly or using an Appearance Proxy. The syntax is similar to UIBarButtonItems as shown above. 76 | 77 | ```objective-c 78 | [BPBarButtonItem customizeSegmentedControl:mySegmentedControl withStyle:BPBarButtonItemStyleStandardDark]; 79 | ``` 80 | 81 | ```objective-c 82 | [BPBarButtonItem customizeSegmentedControl:nil withStyle:BPBarButtonItemStyleStandardDark]; 83 | ``` 84 | 85 | ## Things BPBarButtonItem Can't Do 86 | 87 | BPBarButtonItem makes standard, plain-old `UIBarButtonItem`s, and as such they have the same limitations. You can't use them outside of a navigation bar or a toolbar. If you're looking for a nicely styled `UIButton` alternative, check out [BButton](https://github.com/mattlawer/BButton). 88 | 89 | ## License 90 | 91 | [MIT License](http://opensource.org/licenses/MIT) 92 | 93 | Copyright (c) 2013 Cory Imdieke 94 | 95 | Permission is hereby granted, free of charge, to any person obtaining a copy 96 | of this software and associated documentation files (the "Software"), to deal 97 | in the Software without restriction, including without limitation the rights 98 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 99 | copies of the Software, and to permit persons to whom the Software is 100 | furnished to do so, subject to the following conditions: 101 | 102 | The above copyright notice and this permission notice shall be included in 103 | all copies or substantial portions of the Software. 104 | 105 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 106 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 107 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 108 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 109 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 110 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 111 | THE SOFTWARE. 112 | 113 | ## Contact and Attribution 114 | 115 | Attribution is nice, but not necessary.
116 | https://twitter.com/CoryImdieke 117 | 118 | Thanks to Brian Gilham for help with the design details.
119 | https://twitter.com/bgilham 120 | 121 | [sshot1]:https://raw.github.com/BitSuites/BPBarButtonItem/master/Screenshots/screenshot-1.png 122 | [sshot2]:https://raw.github.com/BitSuites/BPBarButtonItem/master/Screenshots/screenshot-2.png 123 | [sshot3]:https://raw.github.com/BitSuites/BPBarButtonItem/master/Screenshots/screenshot-3.png 124 | [sshot4]:https://raw.github.com/BitSuites/BPBarButtonItem/master/Screenshots/screenshot-4.png 125 | [sshot5]:https://raw.github.com/BitSuites/BPBarButtonItem/master/Screenshots/screenshot-5.png 126 | [sshot6]:https://raw.github.com/BitSuites/BPBarButtonItem/master/Screenshots/screenshot-6.png 127 | -------------------------------------------------------------------------------- /ButtonItemSample/ButtonItemSample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 984F2D97172A0BB7001A387E /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 984F2D96172A0BB7001A387E /* UIKit.framework */; }; 11 | 984F2D99172A0BB7001A387E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 984F2D98172A0BB7001A387E /* Foundation.framework */; }; 12 | 984F2D9B172A0BB7001A387E /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 984F2D9A172A0BB7001A387E /* CoreGraphics.framework */; }; 13 | 984F2DA3172A0BB7001A387E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 984F2DA2172A0BB7001A387E /* main.m */; }; 14 | 984F2DA7172A0BB7001A387E /* SampleAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 984F2DA6172A0BB7001A387E /* SampleAppDelegate.m */; }; 15 | 984F2DA9172A0BB7001A387E /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 984F2DA8172A0BB7001A387E /* Default.png */; }; 16 | 984F2DAB172A0BB7001A387E /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 984F2DAA172A0BB7001A387E /* Default@2x.png */; }; 17 | 984F2DAD172A0BB7001A387E /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 984F2DAC172A0BB7001A387E /* Default-568h@2x.png */; }; 18 | 984F2DB3172A0BB7001A387E /* SampleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 984F2DB2172A0BB7001A387E /* SampleViewController.m */; }; 19 | 984F2DBA172A0C6C001A387E /* MainStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 984F2DB9172A0C6C001A387E /* MainStoryboard.storyboard */; }; 20 | 984F2DBF172A0CDF001A387E /* BPBarButtonItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 984F2DBE172A0CDF001A387E /* BPBarButtonItem.m */; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXFileReference section */ 24 | 984F2D93172A0BB7001A387E /* ButtonItemSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ButtonItemSample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 25 | 984F2D96172A0BB7001A387E /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 26 | 984F2D98172A0BB7001A387E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 27 | 984F2D9A172A0BB7001A387E /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 28 | 984F2D9E172A0BB7001A387E /* ButtonItemSample-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ButtonItemSample-Info.plist"; sourceTree = ""; }; 29 | 984F2DA2172A0BB7001A387E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 30 | 984F2DA4172A0BB7001A387E /* ButtonItemSample-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ButtonItemSample-Prefix.pch"; sourceTree = ""; }; 31 | 984F2DA5172A0BB7001A387E /* SampleAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SampleAppDelegate.h; sourceTree = ""; }; 32 | 984F2DA6172A0BB7001A387E /* SampleAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SampleAppDelegate.m; sourceTree = ""; }; 33 | 984F2DA8172A0BB7001A387E /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; 34 | 984F2DAA172A0BB7001A387E /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; 35 | 984F2DAC172A0BB7001A387E /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 36 | 984F2DB1172A0BB7001A387E /* SampleViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SampleViewController.h; sourceTree = ""; }; 37 | 984F2DB2172A0BB7001A387E /* SampleViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SampleViewController.m; sourceTree = ""; }; 38 | 984F2DB9172A0C6C001A387E /* MainStoryboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = MainStoryboard.storyboard; sourceTree = ""; }; 39 | 984F2DBD172A0CDF001A387E /* BPBarButtonItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BPBarButtonItem.h; sourceTree = ""; }; 40 | 984F2DBE172A0CDF001A387E /* BPBarButtonItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BPBarButtonItem.m; sourceTree = ""; }; 41 | /* End PBXFileReference section */ 42 | 43 | /* Begin PBXFrameworksBuildPhase section */ 44 | 984F2D90172A0BB7001A387E /* Frameworks */ = { 45 | isa = PBXFrameworksBuildPhase; 46 | buildActionMask = 2147483647; 47 | files = ( 48 | 984F2D97172A0BB7001A387E /* UIKit.framework in Frameworks */, 49 | 984F2D99172A0BB7001A387E /* Foundation.framework in Frameworks */, 50 | 984F2D9B172A0BB7001A387E /* CoreGraphics.framework in Frameworks */, 51 | ); 52 | runOnlyForDeploymentPostprocessing = 0; 53 | }; 54 | /* End PBXFrameworksBuildPhase section */ 55 | 56 | /* Begin PBXGroup section */ 57 | 984F2D8A172A0BB7001A387E = { 58 | isa = PBXGroup; 59 | children = ( 60 | 984F2DBC172A0CC0001A387E /* BPBarButtonItem */, 61 | 984F2D9C172A0BB7001A387E /* ButtonItemSample */, 62 | 984F2D95172A0BB7001A387E /* Frameworks */, 63 | 984F2D94172A0BB7001A387E /* Products */, 64 | ); 65 | sourceTree = ""; 66 | }; 67 | 984F2D94172A0BB7001A387E /* Products */ = { 68 | isa = PBXGroup; 69 | children = ( 70 | 984F2D93172A0BB7001A387E /* ButtonItemSample.app */, 71 | ); 72 | name = Products; 73 | sourceTree = ""; 74 | }; 75 | 984F2D95172A0BB7001A387E /* Frameworks */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | 984F2D96172A0BB7001A387E /* UIKit.framework */, 79 | 984F2D98172A0BB7001A387E /* Foundation.framework */, 80 | 984F2D9A172A0BB7001A387E /* CoreGraphics.framework */, 81 | ); 82 | name = Frameworks; 83 | sourceTree = ""; 84 | }; 85 | 984F2D9C172A0BB7001A387E /* ButtonItemSample */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | 984F2DB9172A0C6C001A387E /* MainStoryboard.storyboard */, 89 | 984F2DB1172A0BB7001A387E /* SampleViewController.h */, 90 | 984F2DB2172A0BB7001A387E /* SampleViewController.m */, 91 | 984F2DA5172A0BB7001A387E /* SampleAppDelegate.h */, 92 | 984F2DA6172A0BB7001A387E /* SampleAppDelegate.m */, 93 | 984F2D9D172A0BB7001A387E /* Supporting Files */, 94 | ); 95 | path = ButtonItemSample; 96 | sourceTree = ""; 97 | }; 98 | 984F2D9D172A0BB7001A387E /* Supporting Files */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 984F2D9E172A0BB7001A387E /* ButtonItemSample-Info.plist */, 102 | 984F2DA2172A0BB7001A387E /* main.m */, 103 | 984F2DA4172A0BB7001A387E /* ButtonItemSample-Prefix.pch */, 104 | 984F2DA8172A0BB7001A387E /* Default.png */, 105 | 984F2DAA172A0BB7001A387E /* Default@2x.png */, 106 | 984F2DAC172A0BB7001A387E /* Default-568h@2x.png */, 107 | ); 108 | name = "Supporting Files"; 109 | sourceTree = ""; 110 | }; 111 | 984F2DBC172A0CC0001A387E /* BPBarButtonItem */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | 984F2DBD172A0CDF001A387E /* BPBarButtonItem.h */, 115 | 984F2DBE172A0CDF001A387E /* BPBarButtonItem.m */, 116 | ); 117 | name = BPBarButtonItem; 118 | path = ../BPBarButtonItem; 119 | sourceTree = ""; 120 | }; 121 | /* End PBXGroup section */ 122 | 123 | /* Begin PBXNativeTarget section */ 124 | 984F2D92172A0BB7001A387E /* ButtonItemSample */ = { 125 | isa = PBXNativeTarget; 126 | buildConfigurationList = 984F2DB6172A0BB7001A387E /* Build configuration list for PBXNativeTarget "ButtonItemSample" */; 127 | buildPhases = ( 128 | 984F2D8F172A0BB7001A387E /* Sources */, 129 | 984F2D90172A0BB7001A387E /* Frameworks */, 130 | 984F2D91172A0BB7001A387E /* Resources */, 131 | ); 132 | buildRules = ( 133 | ); 134 | dependencies = ( 135 | ); 136 | name = ButtonItemSample; 137 | productName = ButtonItemSample; 138 | productReference = 984F2D93172A0BB7001A387E /* ButtonItemSample.app */; 139 | productType = "com.apple.product-type.application"; 140 | }; 141 | /* End PBXNativeTarget section */ 142 | 143 | /* Begin PBXProject section */ 144 | 984F2D8B172A0BB7001A387E /* Project object */ = { 145 | isa = PBXProject; 146 | attributes = { 147 | CLASSPREFIX = Sample; 148 | LastUpgradeCheck = 0460; 149 | ORGANIZATIONNAME = "BitSuites, LLC"; 150 | }; 151 | buildConfigurationList = 984F2D8E172A0BB7001A387E /* Build configuration list for PBXProject "ButtonItemSample" */; 152 | compatibilityVersion = "Xcode 3.2"; 153 | developmentRegion = English; 154 | hasScannedForEncodings = 0; 155 | knownRegions = ( 156 | en, 157 | ); 158 | mainGroup = 984F2D8A172A0BB7001A387E; 159 | productRefGroup = 984F2D94172A0BB7001A387E /* Products */; 160 | projectDirPath = ""; 161 | projectRoot = ""; 162 | targets = ( 163 | 984F2D92172A0BB7001A387E /* ButtonItemSample */, 164 | ); 165 | }; 166 | /* End PBXProject section */ 167 | 168 | /* Begin PBXResourcesBuildPhase section */ 169 | 984F2D91172A0BB7001A387E /* Resources */ = { 170 | isa = PBXResourcesBuildPhase; 171 | buildActionMask = 2147483647; 172 | files = ( 173 | 984F2DA9172A0BB7001A387E /* Default.png in Resources */, 174 | 984F2DAB172A0BB7001A387E /* Default@2x.png in Resources */, 175 | 984F2DAD172A0BB7001A387E /* Default-568h@2x.png in Resources */, 176 | 984F2DBA172A0C6C001A387E /* MainStoryboard.storyboard in Resources */, 177 | ); 178 | runOnlyForDeploymentPostprocessing = 0; 179 | }; 180 | /* End PBXResourcesBuildPhase section */ 181 | 182 | /* Begin PBXSourcesBuildPhase section */ 183 | 984F2D8F172A0BB7001A387E /* Sources */ = { 184 | isa = PBXSourcesBuildPhase; 185 | buildActionMask = 2147483647; 186 | files = ( 187 | 984F2DA3172A0BB7001A387E /* main.m in Sources */, 188 | 984F2DA7172A0BB7001A387E /* SampleAppDelegate.m in Sources */, 189 | 984F2DB3172A0BB7001A387E /* SampleViewController.m in Sources */, 190 | 984F2DBF172A0CDF001A387E /* BPBarButtonItem.m in Sources */, 191 | ); 192 | runOnlyForDeploymentPostprocessing = 0; 193 | }; 194 | /* End PBXSourcesBuildPhase section */ 195 | 196 | /* Begin XCBuildConfiguration section */ 197 | 984F2DB4172A0BB7001A387E /* Debug */ = { 198 | isa = XCBuildConfiguration; 199 | buildSettings = { 200 | ALWAYS_SEARCH_USER_PATHS = NO; 201 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 202 | CLANG_CXX_LIBRARY = "libc++"; 203 | CLANG_ENABLE_OBJC_ARC = YES; 204 | CLANG_WARN_CONSTANT_CONVERSION = YES; 205 | CLANG_WARN_EMPTY_BODY = YES; 206 | CLANG_WARN_ENUM_CONVERSION = YES; 207 | CLANG_WARN_INT_CONVERSION = YES; 208 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 209 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 210 | COPY_PHASE_STRIP = NO; 211 | GCC_C_LANGUAGE_STANDARD = gnu99; 212 | GCC_DYNAMIC_NO_PIC = NO; 213 | GCC_OPTIMIZATION_LEVEL = 0; 214 | GCC_PREPROCESSOR_DEFINITIONS = ( 215 | "DEBUG=1", 216 | "$(inherited)", 217 | ); 218 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 219 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 220 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 221 | GCC_WARN_UNUSED_VARIABLE = YES; 222 | IPHONEOS_DEPLOYMENT_TARGET = 6.1; 223 | ONLY_ACTIVE_ARCH = YES; 224 | SDKROOT = iphoneos; 225 | }; 226 | name = Debug; 227 | }; 228 | 984F2DB5172A0BB7001A387E /* Release */ = { 229 | isa = XCBuildConfiguration; 230 | buildSettings = { 231 | ALWAYS_SEARCH_USER_PATHS = NO; 232 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 233 | CLANG_CXX_LIBRARY = "libc++"; 234 | CLANG_ENABLE_OBJC_ARC = YES; 235 | CLANG_WARN_CONSTANT_CONVERSION = YES; 236 | CLANG_WARN_EMPTY_BODY = YES; 237 | CLANG_WARN_ENUM_CONVERSION = YES; 238 | CLANG_WARN_INT_CONVERSION = YES; 239 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 240 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 241 | COPY_PHASE_STRIP = YES; 242 | GCC_C_LANGUAGE_STANDARD = gnu99; 243 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 244 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 245 | GCC_WARN_UNUSED_VARIABLE = YES; 246 | IPHONEOS_DEPLOYMENT_TARGET = 6.1; 247 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 248 | SDKROOT = iphoneos; 249 | VALIDATE_PRODUCT = YES; 250 | }; 251 | name = Release; 252 | }; 253 | 984F2DB7172A0BB7001A387E /* Debug */ = { 254 | isa = XCBuildConfiguration; 255 | buildSettings = { 256 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 257 | GCC_PREFIX_HEADER = "ButtonItemSample/ButtonItemSample-Prefix.pch"; 258 | INFOPLIST_FILE = "ButtonItemSample/ButtonItemSample-Info.plist"; 259 | IPHONEOS_DEPLOYMENT_TARGET = 5.0; 260 | PRODUCT_NAME = "$(TARGET_NAME)"; 261 | WRAPPER_EXTENSION = app; 262 | }; 263 | name = Debug; 264 | }; 265 | 984F2DB8172A0BB7001A387E /* Release */ = { 266 | isa = XCBuildConfiguration; 267 | buildSettings = { 268 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 269 | GCC_PREFIX_HEADER = "ButtonItemSample/ButtonItemSample-Prefix.pch"; 270 | INFOPLIST_FILE = "ButtonItemSample/ButtonItemSample-Info.plist"; 271 | IPHONEOS_DEPLOYMENT_TARGET = 5.0; 272 | PRODUCT_NAME = "$(TARGET_NAME)"; 273 | WRAPPER_EXTENSION = app; 274 | }; 275 | name = Release; 276 | }; 277 | /* End XCBuildConfiguration section */ 278 | 279 | /* Begin XCConfigurationList section */ 280 | 984F2D8E172A0BB7001A387E /* Build configuration list for PBXProject "ButtonItemSample" */ = { 281 | isa = XCConfigurationList; 282 | buildConfigurations = ( 283 | 984F2DB4172A0BB7001A387E /* Debug */, 284 | 984F2DB5172A0BB7001A387E /* Release */, 285 | ); 286 | defaultConfigurationIsVisible = 0; 287 | defaultConfigurationName = Release; 288 | }; 289 | 984F2DB6172A0BB7001A387E /* Build configuration list for PBXNativeTarget "ButtonItemSample" */ = { 290 | isa = XCConfigurationList; 291 | buildConfigurations = ( 292 | 984F2DB7172A0BB7001A387E /* Debug */, 293 | 984F2DB8172A0BB7001A387E /* Release */, 294 | ); 295 | defaultConfigurationIsVisible = 0; 296 | defaultConfigurationName = Release; 297 | }; 298 | /* End XCConfigurationList section */ 299 | }; 300 | rootObject = 984F2D8B172A0BB7001A387E /* Project object */; 301 | } 302 | -------------------------------------------------------------------------------- /BPBarButtonItem/BPBarButtonItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // BPBarButtonItem.m 3 | // 4 | // Created by Cory Imdieke on 4/25/13. 5 | // Copyright (c) 2013 BitSuites, LLC. All rights reserved. 6 | // 7 | 8 | #import "BPBarButtonItem.h" 9 | 10 | 11 | typedef enum : NSInteger { 12 | BPBarButtonItemTypeStandard, 13 | BPBarButtonItemTypeBack 14 | } BPBarButtonItemType; 15 | 16 | #define kActionColor [UIColor colorWithRed:54.0/255.0 green:139.0/255.0 blue:229/255.0 alpha:1.0] 17 | #define kStandardDarkColor [UIColor colorWithWhite:0.25 alpha:1.0] 18 | #define kStandardLightColor [UIColor colorWithRed:0.440 green:0.525 blue:0.673 alpha:1.000] 19 | 20 | @implementation BPBarButtonItem 21 | 22 | + (id)barButtonItemWithStyle:(BPBarButtonItemStyle)style title:(NSString *)title target:(id)target action:(SEL)action{ 23 | if(style == BPBarButtonItemStyleAction) 24 | return [self barButtonItemWithTintColor:kActionColor title:title target:target action:action]; 25 | else if(style == BPBarButtonItemStyleStandardDark) 26 | return [self barButtonItemWithTintColor:kStandardDarkColor title:title target:target action:action]; 27 | else if(style == BPBarButtonItemStyleStandardLight) 28 | return [self barButtonItemWithTintColor:kStandardLightColor title:title target:target action:action]; 29 | 30 | return nil; 31 | } 32 | 33 | + (id)barButtonItemWithTintColor:(UIColor *)tintColor title:(NSString *)title target:(id)target action:(SEL)action{ 34 | UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithTitle:title style:UIBarButtonItemStyleBordered target:target action:action]; 35 | [self customizeBarButtonItem:item withTintColor:tintColor]; 36 | 37 | return item; 38 | } 39 | 40 | + (void)customizeBarButtonItem:(UIBarButtonItem *)item withStyle:(BPBarButtonItemStyle)style{ 41 | if(style == BPBarButtonItemStyleAction) 42 | [self customizeBarButtonItem:item withTintColor:kActionColor]; 43 | else if(style == BPBarButtonItemStyleStandardDark) 44 | [self customizeBarButtonItem:item withTintColor:kStandardDarkColor]; 45 | else if(style == BPBarButtonItemStyleStandardLight) 46 | [self customizeBarButtonItem:item withTintColor:kStandardLightColor]; 47 | } 48 | 49 | + (void)customizeBarButtonItem:(UIBarButtonItem *)item withTintColor:(UIColor *)tintColor{ 50 | // nil button item means customize appearance proxy 51 | if(!item){ 52 | item = [UIBarButtonItem appearance]; 53 | } 54 | 55 | // Portrait Normal Buttons 56 | [item setBackgroundImage:[self stretchableButtonImageForTintColor:tintColor barMetrics:UIBarMetricsDefault forType:BPBarButtonItemTypeStandard] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 57 | [item setBackgroundImage:[self stretchableButtonImageForTintColor:[self lighterColorFromColor:tintColor modificationAmount:0.1] barMetrics:UIBarMetricsDefault forType:BPBarButtonItemTypeStandard] forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault]; 58 | 59 | // Portrait Back Buttons 60 | [item setBackButtonBackgroundImage:[self stretchableButtonImageForTintColor:tintColor barMetrics:UIBarMetricsDefault forType:BPBarButtonItemTypeBack] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 61 | [item setBackButtonBackgroundImage:[self stretchableButtonImageForTintColor:[self lighterColorFromColor:tintColor modificationAmount:0.1] barMetrics:UIBarMetricsDefault forType:BPBarButtonItemTypeBack] forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault]; 62 | [item setBackButtonTitlePositionAdjustment:UIOffsetMake(-1.0, 0.0) forBarMetrics:UIBarMetricsDefault]; 63 | 64 | // Landscape Normal Buttons 65 | [item setBackgroundImage:[self stretchableButtonImageForTintColor:tintColor barMetrics:UIBarMetricsLandscapePhone forType:BPBarButtonItemTypeStandard] forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone]; 66 | [item setBackgroundImage:[self stretchableButtonImageForTintColor:[self lighterColorFromColor:tintColor modificationAmount:0.1] barMetrics:UIBarMetricsLandscapePhone forType:BPBarButtonItemTypeStandard] forState:UIControlStateHighlighted barMetrics:UIBarMetricsLandscapePhone]; 67 | 68 | // Landscape Back Buttons 69 | [item setBackButtonBackgroundImage:[self stretchableButtonImageForTintColor:tintColor barMetrics:UIBarMetricsLandscapePhone forType:BPBarButtonItemTypeBack] forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone]; 70 | [item setBackButtonBackgroundImage:[self stretchableButtonImageForTintColor:[self lighterColorFromColor:tintColor modificationAmount:0.1] barMetrics:UIBarMetricsLandscapePhone forType:BPBarButtonItemTypeBack] forState:UIControlStateHighlighted barMetrics:UIBarMetricsLandscapePhone]; 71 | [item setBackButtonTitlePositionAdjustment:UIOffsetMake(-1.0, 0.0) forBarMetrics:UIBarMetricsLandscapePhone]; 72 | } 73 | 74 | + (void)customizeSegmentedControl:(UISegmentedControl *)segmentedControl withStyle:(BPBarButtonItemStyle)style{ 75 | if(style == BPBarButtonItemStyleAction) 76 | [self customizeSegmentedControl:segmentedControl withTintColor:kActionColor]; 77 | else if(style == BPBarButtonItemStyleStandardDark) 78 | [self customizeSegmentedControl:segmentedControl withTintColor:kStandardDarkColor]; 79 | else if(style == BPBarButtonItemStyleStandardLight) 80 | [self customizeSegmentedControl:segmentedControl withTintColor:kStandardLightColor]; 81 | } 82 | 83 | + (void)customizeSegmentedControl:(UISegmentedControl *)segmentedControl withTintColor:(UIColor *)tintColor{ 84 | // nil segmented control means customize appearance proxy 85 | if(!segmentedControl){ 86 | segmentedControl = [UISegmentedControl appearance]; 87 | } 88 | 89 | // Portrait Segmented Controls 90 | [segmentedControl setBackgroundImage:[self stretchableButtonImageForTintColor:tintColor barMetrics:UIBarMetricsDefault forType:BPBarButtonItemTypeStandard] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 91 | [segmentedControl setBackgroundImage:[self stretchableButtonImageForTintColor:[self lighterColorFromColor:tintColor modificationAmount:0.1] barMetrics:UIBarMetricsDefault forType:BPBarButtonItemTypeStandard] forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault]; 92 | [segmentedControl setBackgroundImage:[self stretchableButtonImageForTintColor:[self lighterColorFromColor:tintColor modificationAmount:0.1] barMetrics:UIBarMetricsDefault forType:BPBarButtonItemTypeStandard] forState:UIControlStateSelected barMetrics:UIBarMetricsDefault]; 93 | [segmentedControl setDividerImage:[self segmentedControlDividerImageForTintColor:tintColor barMetrics:UIBarMetricsDefault] forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 94 | 95 | // Landscape Segmented Controls 96 | [segmentedControl setBackgroundImage:[self stretchableButtonImageForTintColor:tintColor barMetrics:UIBarMetricsLandscapePhone forType:BPBarButtonItemTypeStandard] forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone]; 97 | [segmentedControl setBackgroundImage:[self stretchableButtonImageForTintColor:[self lighterColorFromColor:tintColor modificationAmount:0.1] barMetrics:UIBarMetricsLandscapePhone forType:BPBarButtonItemTypeStandard] forState:UIControlStateHighlighted barMetrics:UIBarMetricsLandscapePhone]; 98 | [segmentedControl setBackgroundImage:[self stretchableButtonImageForTintColor:[self lighterColorFromColor:tintColor modificationAmount:0.1] barMetrics:UIBarMetricsLandscapePhone forType:BPBarButtonItemTypeStandard] forState:UIControlStateSelected barMetrics:UIBarMetricsLandscapePhone]; 99 | [segmentedControl setDividerImage:[self segmentedControlDividerImageForTintColor:tintColor barMetrics:UIBarMetricsLandscapePhone] forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone]; 100 | } 101 | 102 | + (UIImage *)stretchableButtonImageForTintColor:(UIColor *)tintColor barMetrics:(UIBarMetrics)metrics forType:(BPBarButtonItemType)type{ 103 | CGFloat pixelsWide = (type == BPBarButtonItemTypeStandard) ? 9.0 : 23.0; 104 | CGFloat pixelsHigh = (metrics == UIBarMetricsDefault) ? 30.0 : 24.0; 105 | CGFloat drawScale = [[UIScreen mainScreen] scale]; 106 | 107 | UIGraphicsBeginImageContextWithOptions(CGSizeMake(pixelsWide, pixelsHigh), NO, drawScale); 108 | CGContextRef bitmapContext = UIGraphicsGetCurrentContext(); 109 | 110 | [self drawButtonStyleForRect:CGRectMake(0.0, 0.0, pixelsWide, pixelsHigh) inContext:bitmapContext withTintColor:tintColor forType:type]; 111 | 112 | CGImageRef image = CGBitmapContextCreateImage(bitmapContext); 113 | UIImage *newImage = [[UIImage alloc] initWithCGImage:image scale:drawScale orientation:UIImageOrientationUp]; 114 | CGImageRelease(image); 115 | UIGraphicsPopContext(); 116 | 117 | // Insets are a bit different for standard and back buttons for the arrow 118 | UIEdgeInsets insets = (type == BPBarButtonItemTypeStandard) ? UIEdgeInsetsMake(0.0, 4.0, 0.0, 4.0) : UIEdgeInsetsMake(0.0, 15.0, 0.0, 6.0); 119 | 120 | return [newImage resizableImageWithCapInsets:insets]; 121 | } 122 | 123 | + (UIImage *)segmentedControlDividerImageForTintColor:(UIColor *)tintColor barMetrics:(UIBarMetrics)metrics{ 124 | CGFloat pixelsWide = 1.0; 125 | CGFloat pixelsHigh = (metrics == UIBarMetricsDefault) ? 30.0 : 24.0; 126 | CGFloat drawScale = [[UIScreen mainScreen] scale]; 127 | 128 | UIGraphicsBeginImageContextWithOptions(CGSizeMake(pixelsWide, pixelsHigh), NO, drawScale); 129 | CGContextRef bitmapContext = UIGraphicsGetCurrentContext(); 130 | 131 | [self drawSegmentedControlDividerStyleForRect:CGRectMake(0.0, 0.0, pixelsWide, pixelsHigh) inContext:bitmapContext withTintColor:tintColor]; 132 | 133 | CGImageRef image = CGBitmapContextCreateImage(bitmapContext); 134 | UIImage *newImage = [[UIImage alloc] initWithCGImage:image scale:drawScale orientation:UIImageOrientationUp]; 135 | CGImageRelease(image); 136 | UIGraphicsPopContext(); 137 | 138 | return newImage; 139 | } 140 | 141 | + (void)drawButtonStyleForRect:(CGRect)rect inContext:(CGContextRef)context withTintColor:(UIColor *)tintColor forType:(BPBarButtonItemType)type{ 142 | // RGB Space 143 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 144 | 145 | // Colors 146 | UIColor *strokeColor = [[UIColor blackColor] colorWithAlphaComponent:0.6]; 147 | UIColor *bottomShadowColor = [[UIColor whiteColor] colorWithAlphaComponent:0.190]; 148 | UIColor *topGradientColor = [self lighterColorFromColor:tintColor modificationAmount:0.1]; 149 | UIColor *bottomGradientColor = [self darkerColorFromColor:tintColor modificationAmount:0.1]; 150 | 151 | // Button Fill Gradient 152 | CGFloat stopLocations[] = {0.0, 1.0}; 153 | CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)@[(id)topGradientColor.CGColor, (id)bottomGradientColor.CGColor], stopLocations); 154 | 155 | // Button Shadow Values 156 | CGSize bottomShadowOffset = CGSizeMake(0.0, 1.0); 157 | CGFloat bottomShadowBlurRadius = 0.0; 158 | 159 | if(type == BPBarButtonItemTypeStandard){ 160 | // Size Values 161 | CGRect buttonRect = CGRectMake(rect.origin.x + 1.0, rect.origin.y + 1.0, rect.size.width - 2.0, rect.size.height - 3.0); 162 | CGFloat buttonCornerRadius = 4.5; 163 | 164 | // Button Drawing 165 | UIBezierPath *buttonPath = [UIBezierPath bezierPathWithRoundedRect:buttonRect cornerRadius:buttonCornerRadius]; 166 | CGContextSaveGState(context); 167 | [buttonPath addClip]; 168 | CGContextDrawLinearGradient(context, gradient, CGPointZero, CGPointMake(0.0, buttonRect.size.height + 1.0), 0); 169 | CGContextRestoreGState(context); 170 | CGContextSaveGState(context); 171 | CGContextSetShadowWithColor(context, bottomShadowOffset, bottomShadowBlurRadius, bottomShadowColor.CGColor); 172 | [strokeColor setStroke]; 173 | buttonPath.lineWidth = 1.0; 174 | [buttonPath stroke]; 175 | CGContextRestoreGState(context); 176 | } else if(type == BPBarButtonItemTypeBack){ 177 | // Size Values 178 | CGRect buttonRect = CGRectMake(rect.origin.x + 1.0, rect.origin.y + 1.0, rect.size.width - 2.0, rect.size.height - 3.0); 179 | CGFloat buttonPoint = (rect.size.height / 3.0) + 0.5; 180 | 181 | // Back Button Drawing 182 | UIBezierPath *bezierPath = [UIBezierPath bezierPath]; 183 | [bezierPath moveToPoint:CGPointMake(CGRectGetMaxX(buttonRect), CGRectGetMinY(buttonRect) + 5)]; 184 | [bezierPath addLineToPoint:CGPointMake(CGRectGetMaxX(buttonRect), CGRectGetMaxY(buttonRect) - 5)]; 185 | [bezierPath addCurveToPoint:CGPointMake(CGRectGetMaxX(buttonRect) - 5, CGRectGetMaxY(buttonRect)) controlPoint1:CGPointMake(CGRectGetMaxX(buttonRect), CGRectGetMaxY(buttonRect) - 2.24) controlPoint2:CGPointMake(CGRectGetMaxX(buttonRect) - 2.24, CGRectGetMaxY(buttonRect))]; 186 | [bezierPath addLineToPoint:CGPointMake(CGRectGetMinX(buttonRect) + buttonPoint, CGRectGetMaxY(buttonRect))]; 187 | [bezierPath addLineToPoint:CGPointMake(CGRectGetMinX(buttonRect), CGRectGetMinY(buttonRect) + 0.50000 * CGRectGetHeight(buttonRect))]; 188 | [bezierPath addLineToPoint:CGPointMake(CGRectGetMinX(buttonRect) + buttonPoint, CGRectGetMinY(buttonRect))]; 189 | [bezierPath addLineToPoint:CGPointMake(CGRectGetMaxX(buttonRect) - 5, CGRectGetMinY(buttonRect))]; 190 | [bezierPath addCurveToPoint:CGPointMake(CGRectGetMaxX(buttonRect), CGRectGetMinY(buttonRect) + 5) controlPoint1:CGPointMake(CGRectGetMaxX(buttonRect) - 2.24, CGRectGetMinY(buttonRect)) controlPoint2:CGPointMake(CGRectGetMaxX(buttonRect), CGRectGetMinY(buttonRect) + 2.24)]; 191 | [bezierPath closePath]; 192 | CGContextSaveGState(context); 193 | [bezierPath addClip]; 194 | CGRect bezierBounds = CGPathGetPathBoundingBox(bezierPath.CGPath); 195 | CGContextDrawLinearGradient(context, gradient, 196 | CGPointMake(CGRectGetMidX(bezierBounds), CGRectGetMinY(bezierBounds)), 197 | CGPointMake(CGRectGetMidX(bezierBounds), CGRectGetMaxY(bezierBounds)), 198 | 0); 199 | CGContextRestoreGState(context); 200 | CGContextSaveGState(context); 201 | CGContextSetShadowWithColor(context, bottomShadowOffset, bottomShadowBlurRadius, bottomShadowColor.CGColor); 202 | [strokeColor setStroke]; 203 | bezierPath.lineWidth = 1; 204 | [bezierPath stroke]; 205 | CGContextRestoreGState(context); 206 | } 207 | 208 | // Memory Mgmt 209 | CGGradientRelease(gradient); 210 | CGColorSpaceRelease(colorSpace); 211 | } 212 | 213 | + (void)drawSegmentedControlDividerStyleForRect:(CGRect)rect inContext:(CGContextRef)context withTintColor:(UIColor *)tintColor{ 214 | // RGB Space 215 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 216 | 217 | // Colors 218 | UIColor *strokeColor = [[UIColor blackColor] colorWithAlphaComponent:0.6]; 219 | UIColor *bottomShadowColor = [[UIColor whiteColor] colorWithAlphaComponent:0.190]; 220 | 221 | // Divider Shadow Values 222 | CGSize bottomShadowOffset = CGSizeMake(0.0, 1.0); 223 | CGFloat bottomShadowBlurRadius = 0.0; 224 | 225 | // Size Values 226 | CGRect dividerRect = CGRectMake(rect.origin.x, rect.origin.y + 1.0, rect.size.width, rect.size.height - 3.0); 227 | 228 | // Divider Drawing 229 | UIBezierPath *dividerPath = [UIBezierPath bezierPathWithRect:dividerRect]; 230 | CGContextSaveGState(context); 231 | CGContextSetShadowWithColor(context, bottomShadowOffset, bottomShadowBlurRadius, bottomShadowColor.CGColor); 232 | [strokeColor setStroke]; 233 | dividerPath.lineWidth = 1.0; 234 | [dividerPath stroke]; 235 | CGContextRestoreGState(context); 236 | 237 | // Memory Mgmt 238 | CGColorSpaceRelease(colorSpace); 239 | } 240 | 241 | + (UIColor *)darkerColorFromColor:(UIColor *)baseColor modificationAmount:(CGFloat)amount{ 242 | float h, s, b, a, r, g, w; 243 | if([baseColor getRed:&r green:&g blue:&b alpha:&a]){ 244 | return [UIColor colorWithRed:MAX(r - amount, 0.0) 245 | green:MAX(g - amount, 0.0) 246 | blue:MAX(b - amount, 0.0) 247 | alpha:a]; 248 | } else if([baseColor getHue:&h saturation:&s brightness:&b alpha:&a]){ 249 | return [UIColor colorWithHue:h 250 | saturation:s 251 | brightness:b * (1.0 - (amount * 2.0)) 252 | alpha:a]; 253 | } else if([baseColor getWhite:&w alpha:&a]){ 254 | return [UIColor colorWithWhite:MAX(w - amount, 0.0) 255 | alpha:a]; 256 | } 257 | 258 | return nil; 259 | } 260 | 261 | + (UIColor *)lighterColorFromColor:(UIColor *)baseColor modificationAmount:(CGFloat)amount{ 262 | float h, s, b, a, r, g, w; 263 | if([baseColor getRed:&r green:&g blue:&b alpha:&a]){ 264 | return [UIColor colorWithRed:MIN(r + amount, 1.0) 265 | green:MIN(g + amount, 1.0) 266 | blue:MIN(b + amount, 1.0) 267 | alpha:a]; 268 | } else if([baseColor getHue:&h saturation:&s brightness:&b alpha:&a]){ 269 | return [UIColor colorWithHue:h 270 | saturation:s 271 | brightness:MIN(b * (1.0 + amount), 1.0) 272 | alpha:a]; 273 | } else if([baseColor getWhite:&w alpha:&a]){ 274 | return [UIColor colorWithWhite:MAX(w + amount, 0.0) 275 | alpha:a]; 276 | } 277 | return nil; 278 | } 279 | 280 | @end 281 | --------------------------------------------------------------------------------