├── UINavigationItem+Margin ├── UINavigation+Margin.modulemap ├── UINavigationBarContentView+Margin.h ├── UINavigationBarContentViewLayout+Margin.h ├── Swizzle.h ├── Info.plist ├── UINavigationBarContentView+Margin.m ├── UINavigationBarContentViewLayout+Margin.m ├── UINavigationItem+Margin.h ├── Swizzle.m └── UINavigationItem+Margin.m ├── UINavigationItem+Margin.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata ├── xcshareddata │ └── xcschemes │ │ └── UINavigationItem+Margin.xcscheme └── project.pbxproj ├── .gitignore ├── Example ├── ViewController.swift ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Info.plist ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard └── AppDelegate.swift ├── UINavigationItem+Margin.podspec ├── UINavigationItem+MarginTests ├── Info.plist └── UINavigationItem_MarginTests.m ├── .travis.yml ├── LICENSE └── README.md /UINavigationItem+Margin/UINavigation+Margin.modulemap: -------------------------------------------------------------------------------- 1 | framework module UINavigationItem_Margin { 2 | umbrella header "UINavigationItem+Margin.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /UINavigationItem+Margin.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | *.pbxuser 3 | !default.pbxuser 4 | *.mode1v3 5 | !default.mode1v3 6 | *.mode2v3 7 | !default.mode2v3 8 | *.perspectivev3 9 | !default.perspectivev3 10 | xcuserdata 11 | *.xccheckout 12 | *.moved-aside 13 | DerivedData 14 | *.hmap 15 | *.ipa 16 | *.xcuserstate 17 | -------------------------------------------------------------------------------- /UINavigationItem+Margin/UINavigationBarContentView+Margin.h: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationBarContentView+Margin.h 3 | // UINavigationItem+Margin 4 | // 5 | // Created by Suyeol Jeon on 17/10/2017. 6 | // Copyright © 2017 Suyeol Jeon. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSObject (UINavigationBarContentView_Margin) 12 | @end 13 | 14 | -------------------------------------------------------------------------------- /UINavigationItem+Margin/UINavigationBarContentViewLayout+Margin.h: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationBarContentViewLayout+Margin.h 3 | // UINavigationItem+Margin 4 | // 5 | // Created by Suyeol Jeon on 17/10/2017. 6 | // Copyright © 2017 Suyeol Jeon. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSObject (UINavigationBarContentViewLayout_Margin) 12 | @end 13 | -------------------------------------------------------------------------------- /UINavigationItem+Margin/Swizzle.h: -------------------------------------------------------------------------------- 1 | // 2 | // Swizzle.h 3 | // UINavigationItem+Margin 4 | // 5 | // Created by Suyeol Jeon on 17/10/2017. 6 | // Copyright © 2017 Suyeol Jeon. All rights reserved. 7 | // 8 | 9 | void _navigationitem_margin_swizzle_self(Class class, NSString *oldSelectorName); 10 | void _navigationitem_margin_swizzle(Class oldClass, NSString *oldSelectorName, Class newClass); 11 | void swizzleUINavigationBarContentViewIfNeeded(void); 12 | -------------------------------------------------------------------------------- /Example/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Example 4 | // 5 | // Created by Suyeol Jeon on 02/04/2017. 6 | // Copyright © 2017 Suyeol Jeon. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import UINavigationItem_Margin 11 | 12 | class ViewController: UIViewController { 13 | 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | self.navigationItem.leftMargin = 0 17 | self.navigationItem.rightMargin = 0 18 | } 19 | 20 | } 21 | 22 | -------------------------------------------------------------------------------- /UINavigationItem+Margin.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'UINavigationItem+Margin' 3 | s.version = '2.1.1' 4 | s.summary = 'Margin for UINavigationItem.' 5 | s.homepage = 'https://github.com/devxoul/UINavigationItem-Margin' 6 | s.license = { :type => 'MIT', :file => 'LICENSE' } 7 | s.author = { 'Suyeol Jeon' => 'devxoul@gmail.com' } 8 | s.source = { :git => 'https://github.com/devxoul/UINavigationItem-Margin.git', :tag => s.version.to_s } 9 | s.source_files = 'UINavigationItem+Margin/*.{h,m}' 10 | s.frameworks = 'UIKit' 11 | s.requires_arc = true 12 | 13 | s.ios.deployment_target = '7.0' 14 | end 15 | -------------------------------------------------------------------------------- /Example/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /UINavigationItem+MarginTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /UINavigationItem+Margin/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 2.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | osx_image: xcode9 3 | sudo: false 4 | 5 | env: 6 | global: 7 | - PROJECT="UINavigationItem+Margin.xcodeproj" 8 | - SCHEME="UINavigationItem+Margin" 9 | - SDK="iphonesimulator11.0" 10 | - ACTION="test" 11 | matrix: 12 | - IOS_DESTINATION="platform=iOS Simulator,name=iPhone 5S,OS=10.3.1" 13 | - IOS_DESTINATION="platform=iOS Simulator,name=iPhone 6S,OS=10.3.1" 14 | - IOS_DESTINATION="platform=iOS Simulator,name=iPhone 7 Plus,OS=10.3.1" 15 | - IOS_DESTINATION="platform=iOS Simulator,name=iPhone 5S,OS=11.0" 16 | - IOS_DESTINATION="platform=iOS Simulator,name=iPhone 6S,OS=11.0" 17 | - IOS_DESTINATION="platform=iOS Simulator,name=iPhone 7 Plus,OS=11.0" 18 | 19 | script: 20 | - set -o pipefail && xcodebuild clean $ACTION -project "$PROJECT" -scheme "$SCHEME" -sdk "$SDK" -destination "$IOS_DESTINATION" -configuration Debug CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO | xcpretty -c 21 | -------------------------------------------------------------------------------- /UINavigationItem+Margin/UINavigationBarContentView+Margin.m: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationBarContentView+Margin.m 3 | // UINavigationItem+Margin 4 | // 5 | // Created by Suyeol Jeon on 17/10/2017. 6 | // Copyright © 2017 Suyeol Jeon. All rights reserved. 7 | // 8 | 9 | #import "UINavigationBarContentViewLayout+Margin.h" 10 | #import "Swizzle.h" 11 | 12 | @implementation NSObject (UINavigationBarContentViewLayout_Margin) 13 | 14 | void perform(id object, NSString *selectorName) 15 | { 16 | SEL selector = NSSelectorFromString(selectorName); 17 | IMP imp = [object methodForSelector:selector]; 18 | void (*func)(id, SEL) = (void *)imp; 19 | func(object, selector); 20 | } 21 | 22 | - (void)_navigationitem_margin_layoutSubviews { 23 | [self _navigationitem_margin_layoutSubviews]; 24 | if (![NSStringFromClass(self.class) isEqualToString:@"_UINavigationBarContentView"]) { 25 | return; 26 | } 27 | 28 | id layout = [self valueForKey:@"_layout"]; 29 | if (!layout) { 30 | return; 31 | } 32 | perform(layout, @"_updateMarginConstraints"); 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Suyeol Jeon (xoul.kr) 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /UINavigationItem+Margin/UINavigationBarContentViewLayout+Margin.m: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationBarContentViewLayout+Margin.m 3 | // UINavigationItem+Margin 4 | // 5 | // Created by Suyeol Jeon on 17/10/2017. 6 | // Copyright © 2017 Suyeol Jeon. All rights reserved. 7 | // 8 | 9 | #import "UINavigationBarContentViewLayout+Margin.h" 10 | #import "Swizzle.h" 11 | 12 | @implementation NSObject (UINavigationBarContentViewLayout_Margin) 13 | 14 | - (void)_navigationitem_margin__updateMarginConstraints { 15 | [self _navigationitem_margin__updateMarginConstraints]; 16 | [self _manipulateLeadingBarConstraints]; 17 | [self _manipulateTrailingBarConstraints]; 18 | } 19 | 20 | - (void)_manipulateLeadingBarConstraints { 21 | NSArray *leadingBarConstraints = [self valueForKey:@"_leadingBarConstraints"]; 22 | if (!leadingBarConstraints) { 23 | return; 24 | } 25 | for (NSLayoutConstraint *constraint in leadingBarConstraints) { 26 | if (constraint.firstAttribute == NSLayoutAttributeLeading) { 27 | constraint.constant = -16; 28 | } 29 | } 30 | } 31 | 32 | - (void)_manipulateTrailingBarConstraints { 33 | NSArray *trailingBarConstraints = [self valueForKey:@"_trailingBarConstraints"]; 34 | if (!trailingBarConstraints) { 35 | return; 36 | } 37 | for (NSLayoutConstraint *constraint in trailingBarConstraints) { 38 | if (constraint.firstAttribute == NSLayoutAttributeTrailing) { 39 | constraint.constant = 16; 40 | } 41 | } 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /UINavigationItem+Margin/UINavigationItem+Margin.h: -------------------------------------------------------------------------------- 1 | // 2 | // The MIT License (MIT) 3 | // 4 | // Copyright (c) 2015 Suyeol Jeon (xoul.kr) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | #import 26 | #import "UINavigationBarContentViewLayout+Margin.h" 27 | 28 | FOUNDATION_EXPORT double UINavigationItem_MarginVersionNumber; 29 | FOUNDATION_EXPORT const unsigned char UINavigationItem_MarginVersionString[]; 30 | 31 | @interface UINavigationItem (Margin) 32 | 33 | @property (nonatomic, assign) CGFloat leftMargin; 34 | @property (nonatomic, assign) CGFloat rightMargin; 35 | 36 | + (CGFloat)systemMargin; 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | UINavigationItem+Margin 2 | ======================= 3 | 4 | [![Build Status](https://travis-ci.org/devxoul/UINavigationItem-Margin.svg?branch=master)](https://travis-ci.org/devxoul/UINavigationItem-Margin) 5 | [![CocoaPods](http://img.shields.io/cocoapods/v/UINavigationItem+Margin.svg?style=flat)](http://cocoapods.org/?q=name%3AUINavigationItem%2BMargin%20author%3Adevxoul) 6 | 7 | Margin for UINavigationItem. 8 | 9 | 10 | Setting Margins 11 | --------------- 12 | 13 | Just set `leftMargin` and `rightMargin` of your UINavigationItem. 14 | 15 | ```objc 16 | navigationItem.leftMargin = 0; 17 | navigationItem.rightMargin = 0; 18 | ``` 19 | 20 | ![zero](https://cloud.githubusercontent.com/assets/931655/5898748/e1d333a0-a595-11e4-85a3-9a492d1d38fc.png) 21 | 22 | Wow, margin has disappeared. 23 | 24 | Even you can do this: 25 | 26 | ```objc 27 | navigationItem.leftMargin = 50; 28 | navigationItem.rightMargin = 20; 29 | ``` 30 | 31 | ![ugly](https://cloud.githubusercontent.com/assets/931655/6410361/12d1c69e-beb2-11e4-9cf6-7f7d9469ef09.png) 32 | 33 | Looks ugly but works. 34 | 35 | 36 | System Margins 37 | -------------- 38 | 39 | Want to restore margins? Use `[UINavigationItem systemMargin]`. 40 | 41 | ```objc 42 | navigationItem.leftMargin = [UINavigationItem systemMargin]; // 16 on iOS 7+ 43 | navigationItem.rightMargin = [UINavigationItem systemMargin]; 44 | ``` 45 | 46 | ![system](https://cloud.githubusercontent.com/assets/931655/6410333/d42763d6-beb1-11e4-845e-34002d336034.png) 47 | 48 | 49 | Installation 50 | ------------ 51 | 52 | I recommend you to use [CocoaPods](http://cocoapods.org). 53 | 54 | **Podfile** 55 | 56 | ```ruby 57 | pod 'UINavigationItem+Margin' 58 | ``` 59 | 60 | 61 | License 62 | ------- 63 | 64 | **UINavigationItem+Margin** is under MIT license. See the LICENSE file for more info. 65 | -------------------------------------------------------------------------------- /Example/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /UINavigationItem+Margin/Swizzle.m: -------------------------------------------------------------------------------- 1 | // 2 | // Swizzle.m 3 | // UINavigationItem+Margin 4 | // 5 | // Created by Suyeol Jeon on 17/10/2017. 6 | // Copyright © 2017 Suyeol Jeon. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "Swizzle.h" 12 | 13 | void _navigationitem_margin_swizzle_full(Class oldClass, NSString *oldSelectorName, 14 | Class newClass, NSString *newSelectorName) { 15 | Method old = class_getInstanceMethod(oldClass, NSSelectorFromString(oldSelectorName)); 16 | Method new = class_getInstanceMethod(newClass, NSSelectorFromString(newSelectorName)); 17 | method_exchangeImplementations(old, new); 18 | } 19 | 20 | void _navigationitem_margin_swizzle_self(Class class, NSString *oldSelectorName) { 21 | _navigationitem_margin_swizzle(class, oldSelectorName, class); 22 | } 23 | 24 | void _navigationitem_margin_swizzle(Class oldClass, NSString *oldSelectorName, Class newClass) { 25 | NSString *newSelectorName = [NSString stringWithFormat:@"_navigationitem_margin_%@", oldSelectorName]; 26 | _navigationitem_margin_swizzle_full(oldClass, oldSelectorName, newClass, newSelectorName); 27 | } 28 | 29 | void _swizzleUINavigationBarContentView() { 30 | Class class = NSClassFromString(@"_UINavigationBarContentView"); 31 | if (!class) { 32 | return; 33 | } 34 | _navigationitem_margin_swizzle(class, @"layoutSubviews", NSObject.class); 35 | } 36 | 37 | void _swizzleUINavigationBarContentViewLayout() { 38 | Class class = NSClassFromString(@"_UINavigationBarContentViewLayout"); 39 | if (!class) { 40 | return; 41 | } 42 | _navigationitem_margin_swizzle(class, @"_updateMarginConstraints", NSObject.class); 43 | } 44 | 45 | void swizzleUINavigationBarContentViewIfNeeded() { 46 | static dispatch_once_t onceToken; 47 | dispatch_once(&onceToken, ^{ 48 | _swizzleUINavigationBarContentView(); 49 | _swizzleUINavigationBarContentViewLayout(); 50 | }); 51 | } 52 | -------------------------------------------------------------------------------- /Example/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Example 4 | // 5 | // Created by Suyeol Jeon on 02/04/2017. 6 | // Copyright © 2017 Suyeol Jeon. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // 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. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // 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. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // 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. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Example/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 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 | -------------------------------------------------------------------------------- /UINavigationItem+Margin.xcodeproj/xcshareddata/xcschemes/UINavigationItem+Margin.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 45 | 46 | 48 | 54 | 55 | 56 | 57 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 80 | 81 | 87 | 88 | 89 | 90 | 91 | 92 | 98 | 99 | 105 | 106 | 107 | 108 | 110 | 111 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /UINavigationItem+Margin/UINavigationItem+Margin.m: -------------------------------------------------------------------------------- 1 | // 2 | // The MIT License (MIT) 3 | // 4 | // Copyright (c) 2015 Suyeol Jeon (xoul.kr) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | #import 26 | #import 27 | 28 | #import "UINavigationItem+Margin.h" 29 | #import "Swizzle.h" 30 | 31 | #define isCalledFromSystem (BOOL)^(void) { \ 32 | int depth = 3; \ 33 | void *callstack[depth]; \ 34 | int frames = backtrace(callstack, depth); \ 35 | char **symbols = backtrace_symbols(callstack, frames); \ 36 | int contains = 0; \ 37 | if (strstr(symbols[depth - 1], "UIKit") != NULL) { \ 38 | contains = 1; \ 39 | } \ 40 | free(symbols); \ 41 | return contains; \ 42 | }() 43 | #define iOS11 (BOOL)^(void){ \ 44 | if (@available(iOS 11, *)) { \ 45 | return YES; \ 46 | } else { \ 47 | return NO; \ 48 | } \ 49 | }() 50 | 51 | @implementation UINavigationItem (Margin) 52 | 53 | + (void)load { 54 | // left 55 | _navigationitem_margin_swizzle_self(self, @"leftBarButtonItem"); 56 | _navigationitem_margin_swizzle_self(self, @"setLeftBarButtonItem:animated:"); 57 | _navigationitem_margin_swizzle_self(self, @"leftBarButtonItems"); 58 | _navigationitem_margin_swizzle_self(self, @"setLeftBarButtonItems:animated:"); 59 | 60 | // right 61 | _navigationitem_margin_swizzle_self(self, @"rightBarButtonItem"); 62 | _navigationitem_margin_swizzle_self(self, @"setRightBarButtonItem:animated:"); 63 | _navigationitem_margin_swizzle_self(self, @"rightBarButtonItems"); 64 | _navigationitem_margin_swizzle_self(self, @"setRightBarButtonItems:animated:"); 65 | } 66 | 67 | #pragma mark - Global 68 | 69 | + (CGFloat)systemMargin { 70 | return 16; // iOS 7~ 71 | } 72 | 73 | 74 | #pragma mark - Spacer 75 | 76 | - (UIBarButtonItem *)spacerForItem:(UIBarButtonItem *)item withMargin:(CGFloat)margin { 77 | UIBarButtonSystemItem type = UIBarButtonSystemItemFixedSpace; 78 | UIBarButtonItem *spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:type target:self action:nil]; 79 | if (iOS11) { 80 | spacer.width = margin + 8; 81 | } else { 82 | spacer.width = margin - [self.class systemMargin]; 83 | } 84 | 85 | CGFloat screenWidth = UIScreen.mainScreen.bounds.size.width; 86 | 87 | // a margin of private class `UINavigationButton` is different from custom view 88 | if (!iOS11 && !item.customView && screenWidth < 375) { // 3.5 and 4 inch 89 | spacer.width += 8; 90 | } else if (screenWidth >= 414) { // 5.5 inch 91 | spacer.width -= 4; 92 | } 93 | return spacer; 94 | } 95 | 96 | - (UIBarButtonItem *)leftSpacerForItem:(UIBarButtonItem *)item { 97 | return [self spacerForItem:item withMargin:self.leftMargin]; 98 | } 99 | 100 | - (UIBarButtonItem *)rightSpacerForItem:(UIBarButtonItem *)item { 101 | return [self spacerForItem:item withMargin:self.rightMargin]; 102 | } 103 | 104 | 105 | #pragma mark - Margin 106 | 107 | - (void)initializeMarginsIfNeeded { 108 | NSNumber *leftMargin = objc_getAssociatedObject(self, @selector(leftMargin)); 109 | if (!leftMargin) { 110 | self.leftMargin = [self.class systemMargin]; 111 | } 112 | 113 | NSNumber *rightMargin = objc_getAssociatedObject(self, @selector(rightMargin)); 114 | if (!rightMargin) { 115 | self.rightMargin = [self.class systemMargin]; 116 | } 117 | } 118 | 119 | - (CGFloat)leftMargin { 120 | [self initializeMarginsIfNeeded]; 121 | NSNumber *value = objc_getAssociatedObject(self, @selector(leftMargin)); 122 | return value.floatValue; 123 | } 124 | 125 | - (void)setLeftMargin:(CGFloat)leftMargin { 126 | swizzleUINavigationBarContentViewIfNeeded(); 127 | objc_setAssociatedObject(self, @selector(leftMargin), @(leftMargin), OBJC_ASSOCIATION_RETAIN_NONATOMIC); 128 | self.leftBarButtonItems = self.leftBarButtonItems; 129 | } 130 | 131 | - (CGFloat)rightMargin { 132 | [self initializeMarginsIfNeeded]; 133 | NSNumber *value = objc_getAssociatedObject(self, @selector(rightMargin)); 134 | return value.floatValue; 135 | } 136 | 137 | - (void)setRightMargin:(CGFloat)rightMargin { 138 | swizzleUINavigationBarContentViewIfNeeded(); 139 | objc_setAssociatedObject(self, @selector(rightMargin), @(rightMargin), OBJC_ASSOCIATION_RETAIN_NONATOMIC); 140 | self.rightBarButtonItems = self.rightBarButtonItems; 141 | } 142 | 143 | 144 | #pragma mark - Original Bar Button Items 145 | 146 | - (NSArray *)originalLeftBarButtonItems { 147 | NSArray *items = objc_getAssociatedObject(self, @selector(originalLeftBarButtonItems)); 148 | if (!items) { 149 | items = [self _navigationitem_margin_leftBarButtonItems]; 150 | self.originalLeftBarButtonItems = items; 151 | } 152 | return items; 153 | } 154 | 155 | - (void)setOriginalLeftBarButtonItems:(NSArray *)items { 156 | objc_setAssociatedObject(self, @selector(originalLeftBarButtonItems), items, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 157 | } 158 | 159 | - (NSArray *)originalRightBarButtonItems { 160 | NSArray *items = objc_getAssociatedObject(self, @selector(originalRightBarButtonItems)); 161 | if (!items) { 162 | items = [self _navigationitem_margin_rightBarButtonItems]; 163 | self.originalRightBarButtonItems = items; 164 | } 165 | return items; 166 | } 167 | 168 | - (void)setOriginalRightBarButtonItems:(NSArray *)items { 169 | objc_setAssociatedObject(self, @selector(originalRightBarButtonItems), items, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 170 | } 171 | 172 | 173 | #pragma mark - Bar Button Item 174 | 175 | - (UIBarButtonItem *)_navigationitem_margin_leftBarButtonItem { 176 | if (iOS11 && isCalledFromSystem) { 177 | return [self _navigationitem_margin_leftBarButtonItem]; 178 | } else { 179 | return self.originalLeftBarButtonItems.firstObject; 180 | } 181 | } 182 | 183 | - (void)_navigationitem_margin_setLeftBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated { 184 | if (!item) { 185 | [self setLeftBarButtonItems:nil animated:animated]; 186 | } else { 187 | [self setLeftBarButtonItems:@[item] animated:animated]; 188 | } 189 | } 190 | 191 | - (UIBarButtonItem *)_navigationitem_margin_rightBarButtonItem { 192 | if (iOS11 && isCalledFromSystem) { 193 | return [self _navigationitem_margin_rightBarButtonItem]; 194 | } else { 195 | return self.originalRightBarButtonItems.firstObject; 196 | } 197 | } 198 | 199 | - (void)_navigationitem_margin_setRightBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated { 200 | if (!item) { 201 | [self setRightBarButtonItems:nil animated:animated]; 202 | } else { 203 | [self setRightBarButtonItems:@[item] animated:animated]; 204 | } 205 | } 206 | 207 | 208 | #pragma mark - Bar Button Items 209 | 210 | - (NSArray *)_navigationitem_margin_leftBarButtonItems { 211 | if (iOS11 && isCalledFromSystem) { 212 | return [self _navigationitem_margin_leftBarButtonItems]; 213 | } else { 214 | return self.originalLeftBarButtonItems; 215 | } 216 | } 217 | 218 | - (void)_navigationitem_margin_setLeftBarButtonItems:(NSArray *)items animated:(BOOL)animated { 219 | if (items.count) { 220 | self.originalLeftBarButtonItems = items; 221 | UIBarButtonItem *spacer = [self leftSpacerForItem:items.firstObject]; 222 | NSArray *itemsWithMargin = [@[spacer] arrayByAddingObjectsFromArray:items]; 223 | [self _navigationitem_margin_setLeftBarButtonItems:itemsWithMargin animated:animated]; 224 | } else { 225 | self.originalLeftBarButtonItems = nil; 226 | [self _navigationitem_margin_setLeftBarButtonItems:nil animated:animated]; 227 | } 228 | } 229 | 230 | - (NSArray *)_navigationitem_margin_rightBarButtonItems { 231 | if (iOS11 && isCalledFromSystem) { 232 | return [self _navigationitem_margin_rightBarButtonItems]; 233 | } else { 234 | return self.originalRightBarButtonItems; 235 | } 236 | } 237 | 238 | - (void)_navigationitem_margin_setRightBarButtonItems:(NSArray *)items animated:(BOOL)animated { 239 | if (items.count) { 240 | self.originalRightBarButtonItems = items; 241 | UIBarButtonItem *spacer = [self rightSpacerForItem:items.firstObject]; 242 | NSArray *itemsWithMargin = [@[spacer] arrayByAddingObjectsFromArray:items]; 243 | [self _navigationitem_margin_setRightBarButtonItems:itemsWithMargin animated:animated]; 244 | } else { 245 | self.originalRightBarButtonItems = nil; 246 | [self _navigationitem_margin_setRightBarButtonItems:nil animated:animated]; 247 | } 248 | } 249 | 250 | @end 251 | -------------------------------------------------------------------------------- /UINavigationItem+MarginTests/UINavigationItem_MarginTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // The MIT License (MIT) 3 | // 4 | // Copyright (c) 2015 Suyeol Jeon (xoul.kr) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | #import 26 | #import 27 | #import 28 | 29 | @interface UINavigationItem_MarginTests : XCTestCase 30 | 31 | @property (nonatomic, strong) UIWindow *window; 32 | @property (nonatomic, strong) UIViewController *viewController; 33 | @property (nonatomic, strong) UINavigationController *navigationController; 34 | 35 | @property (nonatomic, strong) UIBarButtonItem *editButton; 36 | @property (nonatomic, strong) UIBarButtonItem *doneButton; 37 | @property (nonatomic, strong) UIBarButtonItem *customButton; 38 | 39 | @end 40 | 41 | @implementation UINavigationItem_MarginTests 42 | 43 | - (void)setUp 44 | { 45 | [super setUp]; 46 | 47 | self.viewController = [[UIViewController alloc] init]; 48 | self.navigationController = [[UINavigationController alloc] initWithRootViewController:self.viewController]; 49 | 50 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 51 | 52 | // we cannot use `-[UIWindow makeKeyAndVisible:]` on test environment. 53 | [self.window addSubview:self.navigationController.view]; 54 | 55 | self.editButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit 56 | target:nil 57 | action:nil]; 58 | self.doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone 59 | target:nil 60 | action:nil]; 61 | 62 | UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)]; 63 | customView.backgroundColor = [UIColor redColor]; 64 | self.customButton = [[UIBarButtonItem alloc] initWithCustomView:customView]; 65 | } 66 | 67 | - (void)tearDown 68 | { 69 | self.navigationController.navigationItem.leftMargin = [UINavigationItem systemMargin]; 70 | self.navigationController.navigationItem.rightMargin = [UINavigationItem systemMargin]; 71 | [super tearDown]; 72 | } 73 | 74 | 75 | #pragma mark - 76 | 77 | UIView *rootViewOf(UIView *subview) 78 | { 79 | UIView *rootView = subview; 80 | while (rootView.superview != nil) { 81 | if ([rootView.superview isKindOfClass:UINavigationBar.class]) { 82 | return rootView.superview; 83 | } 84 | rootView = rootView.superview; 85 | } 86 | return rootView; 87 | } 88 | 89 | CGRect relativeRect(UIBarButtonItem *barButtonItem) 90 | { 91 | UIButton *button = [barButtonItem valueForKey:@"view"]; 92 | UIView *rootView = rootViewOf(button); 93 | return [rootView convertRect:button.frame fromView:button.superview]; 94 | } 95 | 96 | CGFloat left(UIBarButtonItem *barButtonItem) 97 | { 98 | return ceil(CGRectGetMinX(relativeRect(barButtonItem))); 99 | } 100 | 101 | CGFloat right(UIBarButtonItem *barButtonItem) 102 | { 103 | UIButton *button = [barButtonItem valueForKey:@"view"]; 104 | UIView *rootView = rootViewOf(button); 105 | return ceil(CGRectGetWidth(rootView.bounds) - CGRectGetMaxX(relativeRect(barButtonItem))); 106 | } 107 | 108 | void perform(id object, NSString *selectorName) 109 | { 110 | SEL selector = NSSelectorFromString(selectorName); 111 | IMP imp = [object methodForSelector:selector]; 112 | void (*func)(id, SEL) = (void *)imp; 113 | func(object, selector); 114 | } 115 | 116 | - (void)layout 117 | { 118 | [self.navigationController.view setNeedsLayout]; 119 | [self.navigationController.view layoutIfNeeded]; 120 | } 121 | 122 | 123 | #pragma mark - Get/Set Items 124 | 125 | - (void)testLeftSetItemGetItem 126 | { 127 | self.viewController.navigationItem.leftBarButtonItem = self.editButton; 128 | XCTAssertEqual(self.viewController.navigationItem.leftBarButtonItem, self.editButton); 129 | } 130 | 131 | - (void)testLeftSetItemGetItems 132 | { 133 | self.viewController.navigationItem.leftBarButtonItem = self.editButton; 134 | XCTAssertEqual(self.viewController.navigationItem.leftBarButtonItems[0], self.editButton); 135 | } 136 | 137 | - (void)testLeftSetItemsGetItem 138 | { 139 | self.viewController.navigationItem.leftBarButtonItems = @[self.editButton, self.doneButton]; 140 | XCTAssertEqual(self.viewController.navigationItem.leftBarButtonItem, self.editButton); 141 | } 142 | 143 | - (void)testLeftSetItemsGetItems 144 | { 145 | self.viewController.navigationItem.leftBarButtonItems = @[self.editButton, self.doneButton]; 146 | XCTAssertEqual(self.viewController.navigationItem.leftBarButtonItems[0], self.editButton); 147 | } 148 | 149 | - (void)testLeftSetNil 150 | { 151 | self.viewController.navigationItem.leftBarButtonItem = nil; 152 | XCTAssertNil(self.viewController.navigationItem.leftBarButtonItem); 153 | } 154 | 155 | - (void)testLeftSetNilAfterSetItem 156 | { 157 | self.viewController.navigationItem.leftBarButtonItem = self.editButton; 158 | self.viewController.navigationItem.leftBarButtonItem = nil; 159 | XCTAssertNil(self.viewController.navigationItem.leftBarButtonItem); 160 | } 161 | 162 | - (void)testLeftSetNilAfterSetItems 163 | { 164 | self.viewController.navigationItem.leftBarButtonItems = @[self.editButton, self.doneButton]; 165 | self.viewController.navigationItem.leftBarButtonItem = nil; 166 | XCTAssertNil(self.viewController.navigationItem.leftBarButtonItem); 167 | } 168 | 169 | - (void)testLeftSetEmptyItems 170 | { 171 | self.viewController.navigationItem.leftBarButtonItems = @[]; 172 | XCTAssertNil(self.viewController.navigationItem.leftBarButtonItem); 173 | } 174 | 175 | - (void)testRightSetItemGetItem 176 | { 177 | self.viewController.navigationItem.rightBarButtonItem = self.editButton; 178 | XCTAssertEqual(self.viewController.navigationItem.rightBarButtonItem, self.editButton); 179 | } 180 | 181 | - (void)testRightSetItemGetItems 182 | { 183 | self.viewController.navigationItem.rightBarButtonItem = self.editButton; 184 | XCTAssertEqual(self.viewController.navigationItem.rightBarButtonItems[0], self.editButton); 185 | } 186 | 187 | - (void)testRightSetItemsGetItem 188 | { 189 | self.viewController.navigationItem.rightBarButtonItems = @[self.editButton, self.doneButton]; 190 | XCTAssertEqual(self.viewController.navigationItem.rightBarButtonItem, self.editButton); 191 | } 192 | 193 | - (void)testRightSetItemsGetItems 194 | { 195 | self.viewController.navigationItem.rightBarButtonItems = @[self.editButton, self.doneButton]; 196 | XCTAssertEqual(self.viewController.navigationItem.rightBarButtonItems[0], self.editButton); 197 | } 198 | 199 | - (void)testRightSetNil 200 | { 201 | self.viewController.navigationItem.rightBarButtonItem = nil; 202 | XCTAssertNil(self.viewController.navigationItem.rightBarButtonItem); 203 | } 204 | 205 | - (void)testRightSetNilAfterSetItem 206 | { 207 | self.viewController.navigationItem.rightBarButtonItem = self.doneButton; 208 | self.viewController.navigationItem.rightBarButtonItem = nil; 209 | XCTAssertNil(self.viewController.navigationItem.rightBarButtonItem); 210 | } 211 | 212 | - (void)testRightSetNilAfterSetItems 213 | { 214 | self.viewController.navigationItem.rightBarButtonItems = @[self.editButton, self.doneButton]; 215 | self.viewController.navigationItem.rightBarButtonItem = nil; 216 | XCTAssertNil(self.viewController.navigationItem.rightBarButtonItem); 217 | } 218 | 219 | - (void)testRightSetEmptyItems 220 | { 221 | self.viewController.navigationItem.rightBarButtonItems = @[]; 222 | XCTAssertNil(self.viewController.navigationItem.rightBarButtonItem); 223 | } 224 | 225 | 226 | #pragma mark - Default Margin 227 | 228 | - (void)testDefaultLeftMargin 229 | { 230 | XCTAssertEqual(self.viewController.navigationItem.leftMargin, [UINavigationItem systemMargin]); 231 | } 232 | 233 | - (void)testDefaultRightMargin 234 | { 235 | XCTAssertEqual(self.viewController.navigationItem.rightMargin, [UINavigationItem systemMargin]); 236 | } 237 | 238 | 239 | #pragma mark - UINavigationItem 240 | 241 | - (void)testLeftMargin_UINavigationItem 242 | { 243 | self.viewController.navigationItem.leftMargin = 10; 244 | self.viewController.navigationItem.leftBarButtonItem = self.editButton; 245 | [self layout]; 246 | XCTAssertEqual(left(self.viewController.navigationItem.leftBarButtonItem), 10); 247 | } 248 | 249 | - (void)testRightMargin_UINavigationItem 250 | { 251 | self.viewController.navigationItem.rightMargin = 11; 252 | self.viewController.navigationItem.rightBarButtonItem = self.doneButton; 253 | [self layout]; 254 | XCTAssertEqual(right(self.viewController.navigationItem.rightBarButtonItem), 11); 255 | } 256 | 257 | - (void)testLeftMargin_UINavigationItem_later 258 | { 259 | self.viewController.navigationItem.leftBarButtonItem = self.editButton; 260 | self.viewController.navigationItem.leftMargin = 12; 261 | [self layout]; 262 | XCTAssertEqual(left(self.viewController.navigationItem.leftBarButtonItem), 12); 263 | } 264 | 265 | - (void)testRightMargin_UINavigationItem_later 266 | { 267 | self.viewController.navigationItem.rightMargin = 13; 268 | self.viewController.navigationItem.rightBarButtonItem = self.doneButton; 269 | [self layout]; 270 | XCTAssertEqual(right(self.viewController.navigationItem.rightBarButtonItem), 13); 271 | } 272 | 273 | 274 | #pragma mark - Custom View 275 | 276 | - (void)testLeftMargin_customView 277 | { 278 | self.viewController.navigationItem.leftMargin = 10; 279 | self.viewController.navigationItem.leftBarButtonItem = self.customButton; 280 | [self layout]; 281 | XCTAssertEqual(left(self.viewController.navigationItem.leftBarButtonItem), 10); 282 | } 283 | 284 | - (void)testRightMargin_customView 285 | { 286 | self.viewController.navigationItem.rightMargin = 10; 287 | self.viewController.navigationItem.rightBarButtonItem = self.customButton; 288 | [self layout]; 289 | XCTAssertEqual(right(self.viewController.navigationItem.rightBarButtonItem), 10); 290 | } 291 | 292 | - (void)testLeftMargin_customView_later 293 | { 294 | self.viewController.navigationItem.leftBarButtonItem = self.customButton; 295 | self.viewController.navigationItem.leftMargin = 10; 296 | [self layout]; 297 | XCTAssertEqual(left(self.viewController.navigationItem.leftBarButtonItem), 10); 298 | } 299 | 300 | - (void)testRightMargin_customView_later 301 | { 302 | self.viewController.navigationItem.rightBarButtonItem = self.customButton; 303 | self.viewController.navigationItem.rightMargin = 10; 304 | [self layout]; 305 | XCTAssertEqual(right(self.viewController.navigationItem.rightBarButtonItem), 10); 306 | } 307 | 308 | @end 309 | -------------------------------------------------------------------------------- /UINavigationItem+Margin.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0344E2FC1A76497D0099CB48 /* UINavigationItem+Margin.h in Headers */ = {isa = PBXBuildFile; fileRef = 0344E2FB1A76497D0099CB48 /* UINavigationItem+Margin.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | 0344E3091A76497D0099CB48 /* UINavigationItem_MarginTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0344E3081A76497D0099CB48 /* UINavigationItem_MarginTests.m */; }; 12 | 0344E3131A7649CE0099CB48 /* UINavigationItem+Margin.m in Sources */ = {isa = PBXBuildFile; fileRef = 0344E3121A7649CE0099CB48 /* UINavigationItem+Margin.m */; }; 13 | 035A065D1E903C7800C4680A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035A065C1E903C7800C4680A /* AppDelegate.swift */; }; 14 | 035A065F1E903C7800C4680A /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035A065E1E903C7800C4680A /* ViewController.swift */; }; 15 | 035A06621E903C7800C4680A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 035A06601E903C7800C4680A /* Main.storyboard */; }; 16 | 035A06641E903C7800C4680A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 035A06631E903C7800C4680A /* Assets.xcassets */; }; 17 | 035A06671E903C7800C4680A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 035A06651E903C7800C4680A /* LaunchScreen.storyboard */; }; 18 | 035A066C1E903CA000C4680A /* UINavigationItem_Margin.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0344E2F61A76497D0099CB48 /* UINavigationItem_Margin.framework */; }; 19 | 035A066D1E903CA000C4680A /* UINavigationItem_Margin.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 0344E2F61A76497D0099CB48 /* UINavigationItem_Margin.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 20 | 03624A911F964224005B2184 /* UINavigationBarContentView+Margin.m in Sources */ = {isa = PBXBuildFile; fileRef = 03624A901F964224005B2184 /* UINavigationBarContentView+Margin.m */; }; 21 | 03A5A97A1F95E90E002357EF /* UINavigationBarContentViewLayout+Margin.h in Headers */ = {isa = PBXBuildFile; fileRef = 03A5A9781F95E90E002357EF /* UINavigationBarContentViewLayout+Margin.h */; settings = {ATTRIBUTES = (Public, ); }; }; 22 | 03A5A97B1F95E90F002357EF /* UINavigationBarContentViewLayout+Margin.m in Sources */ = {isa = PBXBuildFile; fileRef = 03A5A9791F95E90E002357EF /* UINavigationBarContentViewLayout+Margin.m */; }; 23 | 03A5A97E1F95E9CB002357EF /* Swizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = 03A5A97D1F95E9CB002357EF /* Swizzle.m */; }; 24 | 03A5A97F1F95EAE6002357EF /* Swizzle.h in Headers */ = {isa = PBXBuildFile; fileRef = 03A5A97C1F95E99A002357EF /* Swizzle.h */; settings = {ATTRIBUTES = (Private, ); }; }; 25 | 03A5A9951F96234D002357EF /* UINavigationItem_Margin.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0344E2F61A76497D0099CB48 /* UINavigationItem_Margin.framework */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXContainerItemProxy section */ 29 | 035A066E1E903CA000C4680A /* PBXContainerItemProxy */ = { 30 | isa = PBXContainerItemProxy; 31 | containerPortal = 0344E2ED1A76497D0099CB48 /* Project object */; 32 | proxyType = 1; 33 | remoteGlobalIDString = 0344E2F51A76497D0099CB48; 34 | remoteInfo = "UINavigationItem+Margin"; 35 | }; 36 | 03A5A9921F96230D002357EF /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = 0344E2ED1A76497D0099CB48 /* Project object */; 39 | proxyType = 1; 40 | remoteGlobalIDString = 0344E2F51A76497D0099CB48; 41 | remoteInfo = "UINavigationItem+Margin"; 42 | }; 43 | /* End PBXContainerItemProxy section */ 44 | 45 | /* Begin PBXCopyFilesBuildPhase section */ 46 | 035A06701E903CA100C4680A /* Embed Frameworks */ = { 47 | isa = PBXCopyFilesBuildPhase; 48 | buildActionMask = 2147483647; 49 | dstPath = ""; 50 | dstSubfolderSpec = 10; 51 | files = ( 52 | 035A066D1E903CA000C4680A /* UINavigationItem_Margin.framework in Embed Frameworks */, 53 | ); 54 | name = "Embed Frameworks"; 55 | runOnlyForDeploymentPostprocessing = 0; 56 | }; 57 | /* End PBXCopyFilesBuildPhase section */ 58 | 59 | /* Begin PBXFileReference section */ 60 | 0344E2F61A76497D0099CB48 /* UINavigationItem_Margin.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = UINavigationItem_Margin.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 61 | 0344E2FA1A76497D0099CB48 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 62 | 0344E2FB1A76497D0099CB48 /* UINavigationItem+Margin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UINavigationItem+Margin.h"; sourceTree = ""; }; 63 | 0344E3011A76497D0099CB48 /* UINavigationItem+MarginTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "UINavigationItem+MarginTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 64 | 0344E3071A76497D0099CB48 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 65 | 0344E3081A76497D0099CB48 /* UINavigationItem_MarginTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UINavigationItem_MarginTests.m; sourceTree = ""; }; 66 | 0344E3121A7649CE0099CB48 /* UINavigationItem+Margin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UINavigationItem+Margin.m"; sourceTree = ""; }; 67 | 035A06551E903C0400C4680A /* UINavigation+Margin.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = "UINavigation+Margin.modulemap"; sourceTree = ""; }; 68 | 035A065A1E903C7800C4680A /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 69 | 035A065C1E903C7800C4680A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 70 | 035A065E1E903C7800C4680A /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 71 | 035A06611E903C7800C4680A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 72 | 035A06631E903C7800C4680A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 73 | 035A06661E903C7800C4680A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 74 | 035A06681E903C7800C4680A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 75 | 03624A8F1F96421A005B2184 /* UINavigationBarContentView+Margin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UINavigationBarContentView+Margin.h"; sourceTree = ""; }; 76 | 03624A901F964224005B2184 /* UINavigationBarContentView+Margin.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UINavigationBarContentView+Margin.m"; sourceTree = ""; }; 77 | 03A5A9781F95E90E002357EF /* UINavigationBarContentViewLayout+Margin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UINavigationBarContentViewLayout+Margin.h"; sourceTree = ""; }; 78 | 03A5A9791F95E90E002357EF /* UINavigationBarContentViewLayout+Margin.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UINavigationBarContentViewLayout+Margin.m"; sourceTree = ""; }; 79 | 03A5A97C1F95E99A002357EF /* Swizzle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Swizzle.h; sourceTree = ""; }; 80 | 03A5A97D1F95E9CB002357EF /* Swizzle.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Swizzle.m; sourceTree = ""; }; 81 | /* End PBXFileReference section */ 82 | 83 | /* Begin PBXFrameworksBuildPhase section */ 84 | 0344E2F21A76497D0099CB48 /* Frameworks */ = { 85 | isa = PBXFrameworksBuildPhase; 86 | buildActionMask = 2147483647; 87 | files = ( 88 | ); 89 | runOnlyForDeploymentPostprocessing = 0; 90 | }; 91 | 0344E2FE1A76497D0099CB48 /* Frameworks */ = { 92 | isa = PBXFrameworksBuildPhase; 93 | buildActionMask = 2147483647; 94 | files = ( 95 | 03A5A9951F96234D002357EF /* UINavigationItem_Margin.framework in Frameworks */, 96 | ); 97 | runOnlyForDeploymentPostprocessing = 0; 98 | }; 99 | 035A06571E903C7800C4680A /* Frameworks */ = { 100 | isa = PBXFrameworksBuildPhase; 101 | buildActionMask = 2147483647; 102 | files = ( 103 | 035A066C1E903CA000C4680A /* UINavigationItem_Margin.framework in Frameworks */, 104 | ); 105 | runOnlyForDeploymentPostprocessing = 0; 106 | }; 107 | /* End PBXFrameworksBuildPhase section */ 108 | 109 | /* Begin PBXGroup section */ 110 | 0344E2EC1A76497D0099CB48 = { 111 | isa = PBXGroup; 112 | children = ( 113 | 0344E2F81A76497D0099CB48 /* UINavigationItem+Margin */, 114 | 0344E3051A76497D0099CB48 /* UINavigationItem+MarginTests */, 115 | 035A065B1E903C7800C4680A /* Example */, 116 | 0344E2F71A76497D0099CB48 /* Products */, 117 | 03A5A9941F96234D002357EF /* Frameworks */, 118 | ); 119 | indentWidth = 4; 120 | sourceTree = ""; 121 | tabWidth = 4; 122 | }; 123 | 0344E2F71A76497D0099CB48 /* Products */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | 0344E2F61A76497D0099CB48 /* UINavigationItem_Margin.framework */, 127 | 0344E3011A76497D0099CB48 /* UINavigationItem+MarginTests.xctest */, 128 | 035A065A1E903C7800C4680A /* Example.app */, 129 | ); 130 | name = Products; 131 | sourceTree = ""; 132 | }; 133 | 0344E2F81A76497D0099CB48 /* UINavigationItem+Margin */ = { 134 | isa = PBXGroup; 135 | children = ( 136 | 03A5A97C1F95E99A002357EF /* Swizzle.h */, 137 | 03A5A97D1F95E9CB002357EF /* Swizzle.m */, 138 | 0344E2FB1A76497D0099CB48 /* UINavigationItem+Margin.h */, 139 | 0344E3121A7649CE0099CB48 /* UINavigationItem+Margin.m */, 140 | 03624A8F1F96421A005B2184 /* UINavigationBarContentView+Margin.h */, 141 | 03624A901F964224005B2184 /* UINavigationBarContentView+Margin.m */, 142 | 03A5A9781F95E90E002357EF /* UINavigationBarContentViewLayout+Margin.h */, 143 | 03A5A9791F95E90E002357EF /* UINavigationBarContentViewLayout+Margin.m */, 144 | 0344E2F91A76497D0099CB48 /* Supporting Files */, 145 | ); 146 | path = "UINavigationItem+Margin"; 147 | sourceTree = ""; 148 | }; 149 | 0344E2F91A76497D0099CB48 /* Supporting Files */ = { 150 | isa = PBXGroup; 151 | children = ( 152 | 0344E2FA1A76497D0099CB48 /* Info.plist */, 153 | 035A06551E903C0400C4680A /* UINavigation+Margin.modulemap */, 154 | ); 155 | name = "Supporting Files"; 156 | sourceTree = ""; 157 | }; 158 | 0344E3051A76497D0099CB48 /* UINavigationItem+MarginTests */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | 0344E3081A76497D0099CB48 /* UINavigationItem_MarginTests.m */, 162 | 0344E3061A76497D0099CB48 /* Supporting Files */, 163 | ); 164 | path = "UINavigationItem+MarginTests"; 165 | sourceTree = ""; 166 | }; 167 | 0344E3061A76497D0099CB48 /* Supporting Files */ = { 168 | isa = PBXGroup; 169 | children = ( 170 | 0344E3071A76497D0099CB48 /* Info.plist */, 171 | ); 172 | name = "Supporting Files"; 173 | sourceTree = ""; 174 | }; 175 | 035A065B1E903C7800C4680A /* Example */ = { 176 | isa = PBXGroup; 177 | children = ( 178 | 035A065C1E903C7800C4680A /* AppDelegate.swift */, 179 | 035A065E1E903C7800C4680A /* ViewController.swift */, 180 | 035A06601E903C7800C4680A /* Main.storyboard */, 181 | 035A06631E903C7800C4680A /* Assets.xcassets */, 182 | 035A06651E903C7800C4680A /* LaunchScreen.storyboard */, 183 | 035A06681E903C7800C4680A /* Info.plist */, 184 | ); 185 | path = Example; 186 | sourceTree = ""; 187 | }; 188 | 03A5A9941F96234D002357EF /* Frameworks */ = { 189 | isa = PBXGroup; 190 | children = ( 191 | ); 192 | name = Frameworks; 193 | sourceTree = ""; 194 | }; 195 | /* End PBXGroup section */ 196 | 197 | /* Begin PBXHeadersBuildPhase section */ 198 | 0344E2F31A76497D0099CB48 /* Headers */ = { 199 | isa = PBXHeadersBuildPhase; 200 | buildActionMask = 2147483647; 201 | files = ( 202 | 03A5A97A1F95E90E002357EF /* UINavigationBarContentViewLayout+Margin.h in Headers */, 203 | 0344E2FC1A76497D0099CB48 /* UINavigationItem+Margin.h in Headers */, 204 | 03A5A97F1F95EAE6002357EF /* Swizzle.h in Headers */, 205 | ); 206 | runOnlyForDeploymentPostprocessing = 0; 207 | }; 208 | /* End PBXHeadersBuildPhase section */ 209 | 210 | /* Begin PBXNativeTarget section */ 211 | 0344E2F51A76497D0099CB48 /* UINavigationItem+Margin */ = { 212 | isa = PBXNativeTarget; 213 | buildConfigurationList = 0344E30C1A76497D0099CB48 /* Build configuration list for PBXNativeTarget "UINavigationItem+Margin" */; 214 | buildPhases = ( 215 | 0344E2F11A76497D0099CB48 /* Sources */, 216 | 0344E2F21A76497D0099CB48 /* Frameworks */, 217 | 0344E2F31A76497D0099CB48 /* Headers */, 218 | 0344E2F41A76497D0099CB48 /* Resources */, 219 | ); 220 | buildRules = ( 221 | ); 222 | dependencies = ( 223 | ); 224 | name = "UINavigationItem+Margin"; 225 | productName = "UINavigationItem+Margin"; 226 | productReference = 0344E2F61A76497D0099CB48 /* UINavigationItem_Margin.framework */; 227 | productType = "com.apple.product-type.framework"; 228 | }; 229 | 0344E3001A76497D0099CB48 /* UINavigationItem+MarginTests */ = { 230 | isa = PBXNativeTarget; 231 | buildConfigurationList = 0344E30F1A76497D0099CB48 /* Build configuration list for PBXNativeTarget "UINavigationItem+MarginTests" */; 232 | buildPhases = ( 233 | 0344E2FD1A76497D0099CB48 /* Sources */, 234 | 0344E2FE1A76497D0099CB48 /* Frameworks */, 235 | 0344E2FF1A76497D0099CB48 /* Resources */, 236 | ); 237 | buildRules = ( 238 | ); 239 | dependencies = ( 240 | 03A5A9931F96230D002357EF /* PBXTargetDependency */, 241 | ); 242 | name = "UINavigationItem+MarginTests"; 243 | productName = "UINavigationItem+MarginTests"; 244 | productReference = 0344E3011A76497D0099CB48 /* UINavigationItem+MarginTests.xctest */; 245 | productType = "com.apple.product-type.bundle.unit-test"; 246 | }; 247 | 035A06591E903C7800C4680A /* Example */ = { 248 | isa = PBXNativeTarget; 249 | buildConfigurationList = 035A06691E903C7800C4680A /* Build configuration list for PBXNativeTarget "Example" */; 250 | buildPhases = ( 251 | 035A06561E903C7800C4680A /* Sources */, 252 | 035A06571E903C7800C4680A /* Frameworks */, 253 | 035A06581E903C7800C4680A /* Resources */, 254 | 035A06701E903CA100C4680A /* Embed Frameworks */, 255 | ); 256 | buildRules = ( 257 | ); 258 | dependencies = ( 259 | 035A066F1E903CA000C4680A /* PBXTargetDependency */, 260 | ); 261 | name = Example; 262 | productName = Example; 263 | productReference = 035A065A1E903C7800C4680A /* Example.app */; 264 | productType = "com.apple.product-type.application"; 265 | }; 266 | /* End PBXNativeTarget section */ 267 | 268 | /* Begin PBXProject section */ 269 | 0344E2ED1A76497D0099CB48 /* Project object */ = { 270 | isa = PBXProject; 271 | attributes = { 272 | LastSwiftUpdateCheck = 0830; 273 | LastUpgradeCheck = 0900; 274 | ORGANIZATIONNAME = "Suyeol Jeon"; 275 | TargetAttributes = { 276 | 0344E2F51A76497D0099CB48 = { 277 | CreatedOnToolsVersion = 6.2; 278 | }; 279 | 0344E3001A76497D0099CB48 = { 280 | CreatedOnToolsVersion = 6.2; 281 | }; 282 | 035A06591E903C7800C4680A = { 283 | CreatedOnToolsVersion = 8.3; 284 | ProvisioningStyle = Automatic; 285 | }; 286 | }; 287 | }; 288 | buildConfigurationList = 0344E2F01A76497D0099CB48 /* Build configuration list for PBXProject "UINavigationItem+Margin" */; 289 | compatibilityVersion = "Xcode 3.2"; 290 | developmentRegion = English; 291 | hasScannedForEncodings = 0; 292 | knownRegions = ( 293 | en, 294 | Base, 295 | ); 296 | mainGroup = 0344E2EC1A76497D0099CB48; 297 | productRefGroup = 0344E2F71A76497D0099CB48 /* Products */; 298 | projectDirPath = ""; 299 | projectRoot = ""; 300 | targets = ( 301 | 0344E2F51A76497D0099CB48 /* UINavigationItem+Margin */, 302 | 0344E3001A76497D0099CB48 /* UINavigationItem+MarginTests */, 303 | 035A06591E903C7800C4680A /* Example */, 304 | ); 305 | }; 306 | /* End PBXProject section */ 307 | 308 | /* Begin PBXResourcesBuildPhase section */ 309 | 0344E2F41A76497D0099CB48 /* Resources */ = { 310 | isa = PBXResourcesBuildPhase; 311 | buildActionMask = 2147483647; 312 | files = ( 313 | ); 314 | runOnlyForDeploymentPostprocessing = 0; 315 | }; 316 | 0344E2FF1A76497D0099CB48 /* Resources */ = { 317 | isa = PBXResourcesBuildPhase; 318 | buildActionMask = 2147483647; 319 | files = ( 320 | ); 321 | runOnlyForDeploymentPostprocessing = 0; 322 | }; 323 | 035A06581E903C7800C4680A /* Resources */ = { 324 | isa = PBXResourcesBuildPhase; 325 | buildActionMask = 2147483647; 326 | files = ( 327 | 035A06671E903C7800C4680A /* LaunchScreen.storyboard in Resources */, 328 | 035A06641E903C7800C4680A /* Assets.xcassets in Resources */, 329 | 035A06621E903C7800C4680A /* Main.storyboard in Resources */, 330 | ); 331 | runOnlyForDeploymentPostprocessing = 0; 332 | }; 333 | /* End PBXResourcesBuildPhase section */ 334 | 335 | /* Begin PBXSourcesBuildPhase section */ 336 | 0344E2F11A76497D0099CB48 /* Sources */ = { 337 | isa = PBXSourcesBuildPhase; 338 | buildActionMask = 2147483647; 339 | files = ( 340 | 03624A911F964224005B2184 /* UINavigationBarContentView+Margin.m in Sources */, 341 | 03A5A97E1F95E9CB002357EF /* Swizzle.m in Sources */, 342 | 0344E3131A7649CE0099CB48 /* UINavigationItem+Margin.m in Sources */, 343 | 03A5A97B1F95E90F002357EF /* UINavigationBarContentViewLayout+Margin.m in Sources */, 344 | ); 345 | runOnlyForDeploymentPostprocessing = 0; 346 | }; 347 | 0344E2FD1A76497D0099CB48 /* Sources */ = { 348 | isa = PBXSourcesBuildPhase; 349 | buildActionMask = 2147483647; 350 | files = ( 351 | 0344E3091A76497D0099CB48 /* UINavigationItem_MarginTests.m in Sources */, 352 | ); 353 | runOnlyForDeploymentPostprocessing = 0; 354 | }; 355 | 035A06561E903C7800C4680A /* Sources */ = { 356 | isa = PBXSourcesBuildPhase; 357 | buildActionMask = 2147483647; 358 | files = ( 359 | 035A065F1E903C7800C4680A /* ViewController.swift in Sources */, 360 | 035A065D1E903C7800C4680A /* AppDelegate.swift in Sources */, 361 | ); 362 | runOnlyForDeploymentPostprocessing = 0; 363 | }; 364 | /* End PBXSourcesBuildPhase section */ 365 | 366 | /* Begin PBXTargetDependency section */ 367 | 035A066F1E903CA000C4680A /* PBXTargetDependency */ = { 368 | isa = PBXTargetDependency; 369 | target = 0344E2F51A76497D0099CB48 /* UINavigationItem+Margin */; 370 | targetProxy = 035A066E1E903CA000C4680A /* PBXContainerItemProxy */; 371 | }; 372 | 03A5A9931F96230D002357EF /* PBXTargetDependency */ = { 373 | isa = PBXTargetDependency; 374 | target = 0344E2F51A76497D0099CB48 /* UINavigationItem+Margin */; 375 | targetProxy = 03A5A9921F96230D002357EF /* PBXContainerItemProxy */; 376 | }; 377 | /* End PBXTargetDependency section */ 378 | 379 | /* Begin PBXVariantGroup section */ 380 | 035A06601E903C7800C4680A /* Main.storyboard */ = { 381 | isa = PBXVariantGroup; 382 | children = ( 383 | 035A06611E903C7800C4680A /* Base */, 384 | ); 385 | name = Main.storyboard; 386 | sourceTree = ""; 387 | }; 388 | 035A06651E903C7800C4680A /* LaunchScreen.storyboard */ = { 389 | isa = PBXVariantGroup; 390 | children = ( 391 | 035A06661E903C7800C4680A /* Base */, 392 | ); 393 | name = LaunchScreen.storyboard; 394 | sourceTree = ""; 395 | }; 396 | /* End PBXVariantGroup section */ 397 | 398 | /* Begin XCBuildConfiguration section */ 399 | 0344E30A1A76497D0099CB48 /* Debug */ = { 400 | isa = XCBuildConfiguration; 401 | buildSettings = { 402 | ALWAYS_SEARCH_USER_PATHS = NO; 403 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 404 | CLANG_CXX_LIBRARY = "libc++"; 405 | CLANG_ENABLE_MODULES = YES; 406 | CLANG_ENABLE_OBJC_ARC = YES; 407 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 408 | CLANG_WARN_BOOL_CONVERSION = YES; 409 | CLANG_WARN_COMMA = YES; 410 | CLANG_WARN_CONSTANT_CONVERSION = YES; 411 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 412 | CLANG_WARN_EMPTY_BODY = YES; 413 | CLANG_WARN_ENUM_CONVERSION = YES; 414 | CLANG_WARN_INFINITE_RECURSION = YES; 415 | CLANG_WARN_INT_CONVERSION = YES; 416 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 417 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 418 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 419 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 420 | CLANG_WARN_STRICT_PROTOTYPES = YES; 421 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 422 | CLANG_WARN_UNREACHABLE_CODE = YES; 423 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 424 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 425 | COPY_PHASE_STRIP = NO; 426 | CURRENT_PROJECT_VERSION = 1; 427 | ENABLE_STRICT_OBJC_MSGSEND = YES; 428 | ENABLE_TESTABILITY = YES; 429 | GCC_C_LANGUAGE_STANDARD = gnu99; 430 | GCC_DYNAMIC_NO_PIC = NO; 431 | GCC_NO_COMMON_BLOCKS = YES; 432 | GCC_OPTIMIZATION_LEVEL = 0; 433 | GCC_PREPROCESSOR_DEFINITIONS = ( 434 | "DEBUG=1", 435 | "$(inherited)", 436 | ); 437 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 438 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 439 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 440 | GCC_WARN_UNDECLARED_SELECTOR = YES; 441 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 442 | GCC_WARN_UNUSED_FUNCTION = YES; 443 | GCC_WARN_UNUSED_VARIABLE = YES; 444 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 445 | MTL_ENABLE_DEBUG_INFO = YES; 446 | ONLY_ACTIVE_ARCH = YES; 447 | SDKROOT = iphoneos; 448 | SWIFT_VERSION = 4.0; 449 | TARGETED_DEVICE_FAMILY = "1,2"; 450 | VERSIONING_SYSTEM = "apple-generic"; 451 | VERSION_INFO_PREFIX = ""; 452 | }; 453 | name = Debug; 454 | }; 455 | 0344E30B1A76497D0099CB48 /* Release */ = { 456 | isa = XCBuildConfiguration; 457 | buildSettings = { 458 | ALWAYS_SEARCH_USER_PATHS = NO; 459 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 460 | CLANG_CXX_LIBRARY = "libc++"; 461 | CLANG_ENABLE_MODULES = YES; 462 | CLANG_ENABLE_OBJC_ARC = YES; 463 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 464 | CLANG_WARN_BOOL_CONVERSION = YES; 465 | CLANG_WARN_COMMA = YES; 466 | CLANG_WARN_CONSTANT_CONVERSION = YES; 467 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 468 | CLANG_WARN_EMPTY_BODY = YES; 469 | CLANG_WARN_ENUM_CONVERSION = YES; 470 | CLANG_WARN_INFINITE_RECURSION = YES; 471 | CLANG_WARN_INT_CONVERSION = YES; 472 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 473 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 474 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 475 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 476 | CLANG_WARN_STRICT_PROTOTYPES = YES; 477 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 478 | CLANG_WARN_UNREACHABLE_CODE = YES; 479 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 480 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 481 | COPY_PHASE_STRIP = YES; 482 | CURRENT_PROJECT_VERSION = 1; 483 | ENABLE_NS_ASSERTIONS = NO; 484 | ENABLE_STRICT_OBJC_MSGSEND = YES; 485 | GCC_C_LANGUAGE_STANDARD = gnu99; 486 | GCC_NO_COMMON_BLOCKS = YES; 487 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 488 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 489 | GCC_WARN_UNDECLARED_SELECTOR = YES; 490 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 491 | GCC_WARN_UNUSED_FUNCTION = YES; 492 | GCC_WARN_UNUSED_VARIABLE = YES; 493 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 494 | MTL_ENABLE_DEBUG_INFO = NO; 495 | SDKROOT = iphoneos; 496 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 497 | SWIFT_VERSION = 4.0; 498 | TARGETED_DEVICE_FAMILY = "1,2"; 499 | VALIDATE_PRODUCT = YES; 500 | VERSIONING_SYSTEM = "apple-generic"; 501 | VERSION_INFO_PREFIX = ""; 502 | }; 503 | name = Release; 504 | }; 505 | 0344E30D1A76497D0099CB48 /* Debug */ = { 506 | isa = XCBuildConfiguration; 507 | buildSettings = { 508 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 509 | DEFINES_MODULE = YES; 510 | DYLIB_COMPATIBILITY_VERSION = 1; 511 | DYLIB_CURRENT_VERSION = 1; 512 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 513 | INFOPLIST_FILE = "UINavigationItem+Margin/Info.plist"; 514 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 515 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 516 | MODULEMAP_FILE = "UINavigationItem+Margin/UINavigation+Margin.modulemap"; 517 | PRODUCT_BUNDLE_IDENTIFIER = "kr.xoul.$(PRODUCT_NAME:rfc1034identifier)"; 518 | PRODUCT_NAME = UINavigationItem_Margin; 519 | SKIP_INSTALL = YES; 520 | }; 521 | name = Debug; 522 | }; 523 | 0344E30E1A76497D0099CB48 /* Release */ = { 524 | isa = XCBuildConfiguration; 525 | buildSettings = { 526 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 527 | DEFINES_MODULE = YES; 528 | DYLIB_COMPATIBILITY_VERSION = 1; 529 | DYLIB_CURRENT_VERSION = 1; 530 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 531 | INFOPLIST_FILE = "UINavigationItem+Margin/Info.plist"; 532 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 533 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 534 | MODULEMAP_FILE = "UINavigationItem+Margin/UINavigation+Margin.modulemap"; 535 | PRODUCT_BUNDLE_IDENTIFIER = "kr.xoul.$(PRODUCT_NAME:rfc1034identifier)"; 536 | PRODUCT_NAME = UINavigationItem_Margin; 537 | SKIP_INSTALL = YES; 538 | }; 539 | name = Release; 540 | }; 541 | 0344E3101A76497D0099CB48 /* Debug */ = { 542 | isa = XCBuildConfiguration; 543 | buildSettings = { 544 | FRAMEWORK_SEARCH_PATHS = ( 545 | "$(SDKROOT)/Developer/Library/Frameworks", 546 | "$(inherited)", 547 | ); 548 | GCC_PREPROCESSOR_DEFINITIONS = ( 549 | "DEBUG=1", 550 | "$(inherited)", 551 | ); 552 | INFOPLIST_FILE = "UINavigationItem+MarginTests/Info.plist"; 553 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 554 | PRODUCT_BUNDLE_IDENTIFIER = "kr.xoul.$(PRODUCT_NAME:rfc1034identifier)"; 555 | PRODUCT_NAME = "$(TARGET_NAME)"; 556 | }; 557 | name = Debug; 558 | }; 559 | 0344E3111A76497D0099CB48 /* Release */ = { 560 | isa = XCBuildConfiguration; 561 | buildSettings = { 562 | FRAMEWORK_SEARCH_PATHS = ( 563 | "$(SDKROOT)/Developer/Library/Frameworks", 564 | "$(inherited)", 565 | ); 566 | INFOPLIST_FILE = "UINavigationItem+MarginTests/Info.plist"; 567 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 568 | PRODUCT_BUNDLE_IDENTIFIER = "kr.xoul.$(PRODUCT_NAME:rfc1034identifier)"; 569 | PRODUCT_NAME = "$(TARGET_NAME)"; 570 | }; 571 | name = Release; 572 | }; 573 | 035A066A1E903C7800C4680A /* Debug */ = { 574 | isa = XCBuildConfiguration; 575 | buildSettings = { 576 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 577 | CLANG_ANALYZER_NONNULL = YES; 578 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 579 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 580 | CLANG_WARN_INFINITE_RECURSION = YES; 581 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 582 | DEBUG_INFORMATION_FORMAT = dwarf; 583 | ENABLE_TESTABILITY = YES; 584 | GCC_NO_COMMON_BLOCKS = YES; 585 | INFOPLIST_FILE = Example/Info.plist; 586 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 587 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 588 | PRODUCT_BUNDLE_IDENTIFIER = kr.xoul.Example; 589 | PRODUCT_NAME = "$(TARGET_NAME)"; 590 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 591 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 592 | }; 593 | name = Debug; 594 | }; 595 | 035A066B1E903C7800C4680A /* Release */ = { 596 | isa = XCBuildConfiguration; 597 | buildSettings = { 598 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 599 | CLANG_ANALYZER_NONNULL = YES; 600 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 601 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 602 | CLANG_WARN_INFINITE_RECURSION = YES; 603 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 604 | COPY_PHASE_STRIP = NO; 605 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 606 | GCC_NO_COMMON_BLOCKS = YES; 607 | INFOPLIST_FILE = Example/Info.plist; 608 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 609 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 610 | PRODUCT_BUNDLE_IDENTIFIER = kr.xoul.Example; 611 | PRODUCT_NAME = "$(TARGET_NAME)"; 612 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 613 | }; 614 | name = Release; 615 | }; 616 | /* End XCBuildConfiguration section */ 617 | 618 | /* Begin XCConfigurationList section */ 619 | 0344E2F01A76497D0099CB48 /* Build configuration list for PBXProject "UINavigationItem+Margin" */ = { 620 | isa = XCConfigurationList; 621 | buildConfigurations = ( 622 | 0344E30A1A76497D0099CB48 /* Debug */, 623 | 0344E30B1A76497D0099CB48 /* Release */, 624 | ); 625 | defaultConfigurationIsVisible = 0; 626 | defaultConfigurationName = Release; 627 | }; 628 | 0344E30C1A76497D0099CB48 /* Build configuration list for PBXNativeTarget "UINavigationItem+Margin" */ = { 629 | isa = XCConfigurationList; 630 | buildConfigurations = ( 631 | 0344E30D1A76497D0099CB48 /* Debug */, 632 | 0344E30E1A76497D0099CB48 /* Release */, 633 | ); 634 | defaultConfigurationIsVisible = 0; 635 | defaultConfigurationName = Release; 636 | }; 637 | 0344E30F1A76497D0099CB48 /* Build configuration list for PBXNativeTarget "UINavigationItem+MarginTests" */ = { 638 | isa = XCConfigurationList; 639 | buildConfigurations = ( 640 | 0344E3101A76497D0099CB48 /* Debug */, 641 | 0344E3111A76497D0099CB48 /* Release */, 642 | ); 643 | defaultConfigurationIsVisible = 0; 644 | defaultConfigurationName = Release; 645 | }; 646 | 035A06691E903C7800C4680A /* Build configuration list for PBXNativeTarget "Example" */ = { 647 | isa = XCConfigurationList; 648 | buildConfigurations = ( 649 | 035A066A1E903C7800C4680A /* Debug */, 650 | 035A066B1E903C7800C4680A /* Release */, 651 | ); 652 | defaultConfigurationIsVisible = 0; 653 | defaultConfigurationName = Release; 654 | }; 655 | /* End XCConfigurationList section */ 656 | }; 657 | rootObject = 0344E2ED1A76497D0099CB48 /* Project object */; 658 | } 659 | --------------------------------------------------------------------------------