├── snapshot.gif ├── Example ├── MLNavigationBarTransition │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── LaunchImage.launchimage │ │ │ ├── 320X480.png │ │ │ ├── 320X568.png │ │ │ ├── 375x667.png │ │ │ ├── 414x736.png │ │ │ ├── 2436x1125.png │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── UINavigationController+StatusStyle.h │ ├── AppDelegate.h │ ├── ViewController.h │ ├── main.m │ ├── UINavigationController+StatusStyle.m │ ├── BaseViewController.h │ ├── Info.plist │ ├── MLPickerButton │ │ ├── MLPickerButton.h │ │ └── MLPickerButton.m │ ├── AppDelegate.m │ ├── BaseViewController.m │ └── ViewController.m ├── MLNavigationBarTransition.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── project.pbxproj ├── MLNavigationBarTransition.xcworkspace │ └── contents.xcworkspacedata ├── Podfile ├── Podfile.lock ├── MLNavigationBarTransitionTests │ ├── Info.plist │ └── MLNavigationBarTransitionTests.m └── MLNavigationBarTransitionUITests │ ├── Info.plist │ └── MLNavigationBarTransitionUITests.m ├── Classes ├── UINavigationController+MLNavigationBarTransition.h ├── NSString+MLNavigationBarTransition_Encrypt.h ├── NSString+MLNavigationBarTransition_Encrypt.m ├── UINavigationBar+MLNavigationBarTransition.h ├── MLNavigationBarTransitionDefine.h ├── UINavigationController+MLNavigationBarTransition.m └── UINavigationBar+MLNavigationBarTransition.m ├── .travis.yml ├── MLNavigationBarTransition.podspec ├── LICENSE ├── .gitignore └── README.md /snapshot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/molon/MLNavigationBarTransition/HEAD/snapshot.gif -------------------------------------------------------------------------------- /Example/MLNavigationBarTransition/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/MLNavigationBarTransition/Assets.xcassets/LaunchImage.launchimage/320X480.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/molon/MLNavigationBarTransition/HEAD/Example/MLNavigationBarTransition/Assets.xcassets/LaunchImage.launchimage/320X480.png -------------------------------------------------------------------------------- /Example/MLNavigationBarTransition/Assets.xcassets/LaunchImage.launchimage/320X568.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/molon/MLNavigationBarTransition/HEAD/Example/MLNavigationBarTransition/Assets.xcassets/LaunchImage.launchimage/320X568.png -------------------------------------------------------------------------------- /Example/MLNavigationBarTransition/Assets.xcassets/LaunchImage.launchimage/375x667.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/molon/MLNavigationBarTransition/HEAD/Example/MLNavigationBarTransition/Assets.xcassets/LaunchImage.launchimage/375x667.png -------------------------------------------------------------------------------- /Example/MLNavigationBarTransition/Assets.xcassets/LaunchImage.launchimage/414x736.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/molon/MLNavigationBarTransition/HEAD/Example/MLNavigationBarTransition/Assets.xcassets/LaunchImage.launchimage/414x736.png -------------------------------------------------------------------------------- /Example/MLNavigationBarTransition/Assets.xcassets/LaunchImage.launchimage/2436x1125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/molon/MLNavigationBarTransition/HEAD/Example/MLNavigationBarTransition/Assets.xcassets/LaunchImage.launchimage/2436x1125.png -------------------------------------------------------------------------------- /Example/MLNavigationBarTransition.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/MLNavigationBarTransition.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/MLNavigationBarTransition/UINavigationController+StatusStyle.h: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationController+StatusStyle.h 3 | // MLNavigationBarTransition 4 | // 5 | // Created by molon on 2016/11/30. 6 | // Copyright © 2016年 molon. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UINavigationController (StatusStyle) 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Classes/UINavigationController+MLNavigationBarTransition.h: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationController+MLNavigationBarTransition.h 3 | // MLNavigationBarTransition 4 | // 5 | // Created by molon on 2016/11/28. 6 | // Copyright © 2016年 molon. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UINavigationController (MLNavigationBarTransition) 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Classes/NSString+MLNavigationBarTransition_Encrypt.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+MLNavigationBarTransition_Encrypt.h 3 | // Pods 4 | // 5 | // Created by molon on 2017/1/6. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (MLNavigationBarTransition_Encrypt) 12 | 13 | - (NSString *)mlnbt_EncryptString; 14 | - (NSString *)mlnbt_DecryptString; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | 3 | platform :ios, '7.0' 4 | 5 | workspace 'MLNavigationBarTransition.xcworkspace' 6 | 7 | target 'MLNavigationBarTransition' do 8 | project 'MLNavigationBarTransition.xcodeproj' 9 | 10 | pod 'MLTransition', '~> 2.1.2' 11 | pod 'MLNavigationBarTransition', :path => '../MLNavigationBarTransition.podspec' 12 | end 13 | -------------------------------------------------------------------------------- /Example/MLNavigationBarTransition/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // MLNavigationBarTransition 4 | // 5 | // Created by molon on 2016/11/27. 6 | // Copyright © 2016年 molon. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /Example/MLNavigationBarTransition/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // MLNavigationBarTransition 4 | // 5 | // Created by molon on 2016/11/27. 6 | // Copyright © 2016年 molon. All rights reserved. 7 | // 8 | 9 | #import "BaseViewController.h" 10 | 11 | @interface ViewController : BaseViewController 12 | 13 | @property (nonatomic, strong) NSMutableArray *configs; 14 | 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /Example/MLNavigationBarTransition/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // MLNavigationBarTransition 4 | // 5 | // Created by molon on 2016/11/27. 6 | // Copyright © 2016年 molon. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | osx_image: xcode8 3 | notifications: 4 | email: 5 | - dudl@qq.com 6 | # after_success: 7 | # - bash <(curl -s https://codecov.io/bash) 8 | 9 | podfile: Example/Podfile 10 | script: 11 | xcodebuild 12 | -workspace Example/MLNavigationBarTransition.xcworkspace 13 | -scheme MLNavigationBarTransition 14 | -sdk iphonesimulator 15 | ONLY_ACTIVE_ARCH=NO 16 | CODE_SIGN_IDENTITY="" 17 | CODE_SIGNING_REQUIRED=NO -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - MLNavigationBarTransition (0.0.2) 3 | - MLTransition (2.1.2) 4 | 5 | DEPENDENCIES: 6 | - MLNavigationBarTransition (from `../MLNavigationBarTransition.podspec`) 7 | - MLTransition (~> 2.1.2) 8 | 9 | EXTERNAL SOURCES: 10 | MLNavigationBarTransition: 11 | :path: "../MLNavigationBarTransition.podspec" 12 | 13 | SPEC CHECKSUMS: 14 | MLNavigationBarTransition: 5c5100985d84c1d106d65a37dcce1bf7b7c89b8f 15 | MLTransition: 26751adac088c07e4df48c9f605cfdd767bb8afa 16 | 17 | PODFILE CHECKSUM: f03d0520d967396f8f27c942de56700749119edc 18 | 19 | COCOAPODS: 1.2.1 20 | -------------------------------------------------------------------------------- /Example/MLNavigationBarTransition/UINavigationController+StatusStyle.m: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationController+StatusStyle.m 3 | // MLNavigationBarTransition 4 | // 5 | // Created by molon on 2016/11/30. 6 | // Copyright © 2016年 molon. All rights reserved. 7 | // 8 | 9 | #import "UINavigationController+StatusStyle.h" 10 | 11 | @implementation UINavigationController (StatusStyle) 12 | 13 | - (UIViewController *)childViewControllerForStatusBarStyle { 14 | return self.topViewController; 15 | } 16 | 17 | - (UIViewController *)childViewControllerForStatusBarHidden { 18 | return self.topViewController; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /MLNavigationBarTransition.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "MLNavigationBarTransition" 3 | s.version = "0.0.7" 4 | s.summary = "Advanced navigation bar transition based on official push-pop transition" 5 | 6 | s.homepage = 'https://github.com/molon/MLNavigationBarTransition' 7 | s.license = { :type => 'MIT'} 8 | s.author = { "molon" => "dudl@qq.com" } 9 | 10 | s.source = { 11 | :git => "https://github.com/molon/MLNavigationBarTransition.git", 12 | :tag => "#{s.version}" 13 | } 14 | 15 | s.platform = :ios, '7.0' 16 | s.public_header_files = 'Classes/**/*.h' 17 | s.source_files = 'Classes/**/*.{h,m,c}' 18 | s.requires_arc = true 19 | 20 | end 21 | -------------------------------------------------------------------------------- /Example/MLNavigationBarTransitionTests/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 | -------------------------------------------------------------------------------- /Example/MLNavigationBarTransitionUITests/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 | -------------------------------------------------------------------------------- /Example/MLNavigationBarTransition/BaseViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BaseViewController.h 3 | // MLNavigationBarTransition 4 | // 5 | // Created by molon on 2016/11/30. 6 | // Copyright © 2016年 molon. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MLNavigationBarConfig : NSObject 12 | 13 | @property (nonatomic, strong) UIColor *barTintColor; 14 | @property (nonatomic, strong) UIColor *barBackgroundImageColor; 15 | 16 | @property (nonatomic, strong) UIColor *titleColor; 17 | @property (nonatomic, strong) UIColor *itemColor; 18 | 19 | @property (nonatomic, assign) BOOL showShadowImage; 20 | 21 | @property (nonatomic, assign) CGFloat backgroundAlpha; 22 | 23 | @end 24 | 25 | @interface BaseViewController : UIViewController 26 | 27 | @property (nonatomic, strong) MLNavigationBarConfig *navigationBarConfig; 28 | 29 | - (void)updateNavigationBarDisplay; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 molon 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/MLNavigationBarTransitionTests/MLNavigationBarTransitionTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // MLNavigationBarTransitionTests.m 3 | // MLNavigationBarTransitionTests 4 | // 5 | // Created by molon on 2016/11/27. 6 | // Copyright © 2016年 molon. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MLNavigationBarTransitionTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation MLNavigationBarTransitionTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /Example/MLNavigationBarTransition/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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UIRequiredDeviceCapabilities 26 | 27 | armv7 28 | 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | 33 | UISupportedInterfaceOrientations~ipad 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationPortraitUpsideDown 37 | UIInterfaceOrientationLandscapeLeft 38 | UIInterfaceOrientationLandscapeRight 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Example/MLNavigationBarTransitionUITests/MLNavigationBarTransitionUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // MLNavigationBarTransitionUITests.m 3 | // MLNavigationBarTransitionUITests 4 | // 5 | // Created by molon on 2016/11/27. 6 | // Copyright © 2016年 molon. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MLNavigationBarTransitionUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation MLNavigationBarTransitionUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | # CocoaPods 32 | # 33 | # We recommend against adding the Pods directory to your .gitignore. However 34 | # you should judge for yourself, the pros and cons are mentioned at: 35 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 36 | # 37 | Pods/ 38 | Example/Pods/ 39 | 40 | # Carthage 41 | # 42 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 43 | # Carthage/Checkouts 44 | 45 | Carthage/Build 46 | 47 | # fastlane 48 | # 49 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 50 | # screenshots whenever they are needed. 51 | # For more information about the recommended setup visit: 52 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 53 | 54 | fastlane/report.xml 55 | fastlane/screenshots 56 | 57 | # Code Injection 58 | # 59 | # After new code Injection tools there's a generated folder /iOSInjectionProject 60 | # https://github.com/johnno1962/injectionforxcode 61 | 62 | iOSInjectionProject/ -------------------------------------------------------------------------------- /Classes/NSString+MLNavigationBarTransition_Encrypt.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+MLNavigationBarTransition_Encrypt.m 3 | // Pods 4 | // 5 | // Created by molon on 2017/1/6. 6 | // 7 | // 8 | 9 | #import "NSString+MLNavigationBarTransition_Encrypt.h" 10 | #import "MLNavigationBarTransitionDefine.h" 11 | 12 | MLNBT_SYNTH_DUMMY_CLASS(NSString_MLNavigationBarTransition_Encrypt) 13 | 14 | @implementation NSString (MLNavigationBarTransition_Encrypt) 15 | 16 | - (NSString *)__mlnbt_Rot13 { 17 | const char *source = [self cStringUsingEncoding:NSASCIIStringEncoding]; 18 | char *dest = (char *)malloc((self.length + 1) * sizeof(char)); 19 | if (!dest) { 20 | return nil; 21 | } 22 | 23 | NSUInteger i = 0; 24 | for ( ; i < self.length; i++) { 25 | char c = source[i]; 26 | if (c >= 'A' && c <= 'Z') { 27 | c = (c - 'A' + 13) % 26 + 'A'; 28 | } 29 | else if (c >= 'a' && c <= 'z') { 30 | c = (c - 'a' + 13) % 26 + 'a'; 31 | } 32 | dest[i] = c; 33 | } 34 | dest[i] = '\0'; 35 | 36 | NSString *result = [[NSString alloc] initWithCString:dest encoding:NSASCIIStringEncoding]; 37 | free(dest); 38 | 39 | return result; 40 | } 41 | 42 | - (NSString *)mlnbt_EncryptString { 43 | NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding]; 44 | NSString *base64 = [data base64EncodedStringWithOptions:0]; 45 | return [base64 __mlnbt_Rot13]; 46 | } 47 | 48 | - (NSString *)mlnbt_DecryptString { 49 | NSString *rot13 = [self __mlnbt_Rot13]; 50 | NSData *data = [[NSData alloc] initWithBase64EncodedString:rot13 options:0]; 51 | return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 52 | } 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /Classes/UINavigationBar+MLNavigationBarTransition.h: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationBar+MLNavigationBarTransition.h 3 | // MLNavigationBarTransition 4 | // 5 | // Created by molon on 2016/11/29. 6 | // Copyright © 2016年 molon. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface UINavigationBar (MLNavigationBarTransition) 14 | 15 | /** 16 | back indicator image view 17 | */ 18 | @property (nullable, nonatomic, strong, readonly) UIView *ml_backIndicatorView; 19 | 20 | /** 21 | label on back button 22 | */ 23 | @property (nullable ,nonatomic, strong, readonly) UILabel *ml_backButtonLabel; 24 | 25 | /** 26 | the shadow image view 27 | */ 28 | @property (nullable, nonatomic, strong, readonly) UIView *ml_backgroundShadowView; 29 | 30 | /** 31 | The colored background view of bar 32 | @warning Can't set ml_backgroundView.alpha directly, please use `setMl_backgroundAlpha:` 33 | */ 34 | @property (nullable, nonatomic, strong, readonly) UIView *ml_backgroundView; 35 | 36 | /** 37 | Current displaying backgroundImage 38 | */ 39 | @property (nullable, nonatomic, strong, readonly) UIImage *ml_currentBackgroundImage; 40 | 41 | /** 42 | Current displaying background alpha 43 | @warning If you want to change ml_backgroundView.alpha, please use this. 44 | */ 45 | @property (nonatomic, assign) CGFloat ml_backgroundAlpha; 46 | 47 | /** 48 | Returns a replicant of the same background effect 49 | */ 50 | - (nullable UINavigationBar*)ml_replicantBarOfSameBackgroundEffectWithContainerView:(UIView*)containerView; 51 | 52 | /** 53 | Whether one bar same background effect with other one 54 | 55 | @param navigationBar navigationBar 56 | 57 | @return bool 58 | */ 59 | - (BOOL)ml_isSameBackgroundEffectToNavigationBar:(UINavigationBar*)navigationBar; 60 | 61 | @end 62 | 63 | NS_ASSUME_NONNULL_END 64 | -------------------------------------------------------------------------------- /Example/MLNavigationBarTransition/MLPickerButton/MLPickerButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // MLPickerButton.h 3 | // InventoryTool 4 | // 5 | // Created by molon on 14-1-22. 6 | // Copyright (c) 2014年 Molon. All rights reserved. 7 | // 8 | /** 9 | * 10 | - (void)doneWithPickerButton:(MLPickerButton*)pickerButton 11 | { 12 | //获取当前选择行 13 | NSUInteger currentSelectedRow = [pickerButton.pickerView selectedRowInComponent:0]; 14 | //选择某行 15 | [pickerButton.pickerView selectRow:0 inComponent:0 animated:YES]; 16 | } 17 | */ 18 | 19 | #import 20 | @class MLPickerButton; 21 | 22 | @protocol MLPickerButtonDelegate 23 | 24 | - (void)doneWithPickerButton:(MLPickerButton*)pickerButton; 25 | 26 | @optional 27 | - (void)didSelectWithPickerButton:(MLPickerButton*)pickerButton; 28 | 29 | - (BOOL)shouldBecomeFirstResponderWithPickerButton:(MLPickerButton*)pickerButton; 30 | - (void)resignFirstResponderWithPickerButton:(MLPickerButton*)pickerButton; 31 | - (void)becomeFirstResponderWithPickerButton:(MLPickerButton*)pickerButton; 32 | 33 | //自定义取消事件 34 | - (void)customClickCancle; 35 | - (NSString*)customCancelTitle; 36 | 37 | @end 38 | 39 | @interface MLPickerButton : UIButton 40 | 41 | @property (nonatomic,weak) id delegate; 42 | @property (nonatomic,copy) NSString *pickerTitle; //toolBar上面的标题 43 | 44 | @property (nonatomic, assign) BOOL dontDisplayDimmingView; //不显示黑色遮罩 45 | 46 | @property (nonatomic,weak,readonly) UIPickerView *pickerView; //其实就是inputView 47 | 48 | //默认只能使用单列picker,需要多列需要设置pickerDelegate和pickerDataSource并自己定制 49 | @property (nonatomic,strong) NSArray *dataOfSingleComponentPicker; //只包含NSString作为项的单列Picker 50 | 51 | @property (nonatomic, strong) id userInfo; 52 | 53 | //下面俩任何一个不设置则会认为使用Button作为Picker的delegate,同时需要传递单列数组 54 | //若两个都设置,则dataOfSingleComponentPicker会被忽略。 55 | //认为自己维护Picker数据 56 | @property (nonatomic,weak) id pickerDelegate; 57 | @property (nonatomic,weak) id pickerDataSource; 58 | 59 | 60 | - (void)touchUpInSide; 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /Example/MLNavigationBarTransition/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /Example/MLNavigationBarTransition/Assets.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "extent" : "full-screen", 5 | "idiom" : "iphone", 6 | "subtype" : "2436h", 7 | "filename" : "2436x1125.png", 8 | "minimum-system-version" : "11.0", 9 | "orientation" : "portrait", 10 | "scale" : "3x" 11 | }, 12 | { 13 | "orientation" : "landscape", 14 | "idiom" : "iphone", 15 | "extent" : "full-screen", 16 | "minimum-system-version" : "11.0", 17 | "subtype" : "2436h", 18 | "scale" : "3x" 19 | }, 20 | { 21 | "extent" : "full-screen", 22 | "idiom" : "iphone", 23 | "subtype" : "736h", 24 | "filename" : "414x736.png", 25 | "minimum-system-version" : "8.0", 26 | "orientation" : "portrait", 27 | "scale" : "3x" 28 | }, 29 | { 30 | "orientation" : "landscape", 31 | "idiom" : "iphone", 32 | "extent" : "full-screen", 33 | "minimum-system-version" : "8.0", 34 | "subtype" : "736h", 35 | "scale" : "3x" 36 | }, 37 | { 38 | "extent" : "full-screen", 39 | "idiom" : "iphone", 40 | "subtype" : "667h", 41 | "filename" : "375x667.png", 42 | "minimum-system-version" : "8.0", 43 | "orientation" : "portrait", 44 | "scale" : "2x" 45 | }, 46 | { 47 | "orientation" : "portrait", 48 | "idiom" : "iphone", 49 | "filename" : "320X480.png", 50 | "extent" : "full-screen", 51 | "minimum-system-version" : "7.0", 52 | "scale" : "2x" 53 | }, 54 | { 55 | "extent" : "full-screen", 56 | "idiom" : "iphone", 57 | "subtype" : "retina4", 58 | "filename" : "320X568.png", 59 | "minimum-system-version" : "7.0", 60 | "orientation" : "portrait", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "orientation" : "portrait", 65 | "idiom" : "iphone", 66 | "extent" : "full-screen", 67 | "scale" : "1x" 68 | }, 69 | { 70 | "orientation" : "portrait", 71 | "idiom" : "iphone", 72 | "extent" : "full-screen", 73 | "scale" : "2x" 74 | }, 75 | { 76 | "orientation" : "portrait", 77 | "idiom" : "iphone", 78 | "extent" : "full-screen", 79 | "subtype" : "retina4", 80 | "scale" : "2x" 81 | } 82 | ], 83 | "info" : { 84 | "version" : 1, 85 | "author" : "xcode" 86 | } 87 | } -------------------------------------------------------------------------------- /Example/MLNavigationBarTransition/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // MLNavigationBarTransition 4 | // 5 | // Created by molon on 2016/11/27. 6 | // Copyright © 2016年 molon. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "ViewController.h" 11 | #import 12 | 13 | @interface AppDelegate () 14 | 15 | @end 16 | 17 | @implementation AppDelegate 18 | 19 | 20 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 21 | [MLTransition validatePanBackWithMLTransitionGestureRecognizerType:MLTransitionGestureRecognizerTypePan]; 22 | // Override point for customization after application launch. 23 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 24 | self.window.backgroundColor = [UIColor whiteColor]; 25 | 26 | self.window.rootViewController = [[UINavigationController alloc]initWithRootViewController:[ViewController new]]; 27 | [self.window makeKeyAndVisible]; 28 | 29 | // [self.window.layer setSpeed:.1f]; 30 | 31 | return YES; 32 | } 33 | 34 | - (void)applicationWillResignActive:(UIApplication *)application { 35 | // 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. 36 | // 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. 37 | } 38 | 39 | - (void)applicationDidEnterBackground:(UIApplication *)application { 40 | // 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. 41 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 42 | } 43 | 44 | - (void)applicationWillEnterForeground:(UIApplication *)application { 45 | // 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. 46 | } 47 | 48 | - (void)applicationDidBecomeActive:(UIApplication *)application { 49 | // 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. 50 | } 51 | 52 | - (void)applicationWillTerminate:(UIApplication *)application { 53 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /Example/MLNavigationBarTransition/BaseViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // BaseViewController.m 3 | // MLNavigationBarTransition 4 | // 5 | // Created by molon on 2016/11/30. 6 | // Copyright © 2016年 molon. All rights reserved. 7 | // 8 | 9 | #import "BaseViewController.h" 10 | #import 11 | 12 | static inline UIImage *kImageWithColor(UIColor *color) { 13 | if (!color) { 14 | return nil; 15 | } 16 | CGSize size = CGSizeMake(1, 1); 17 | CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height); 18 | UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0); 19 | CGContextRef context = UIGraphicsGetCurrentContext(); 20 | CGContextSetFillColorWithColor(context, color.CGColor); 21 | CGContextFillRect(context, rect); 22 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 23 | UIGraphicsEndImageContext(); 24 | return image; 25 | } 26 | 27 | @implementation MLNavigationBarConfig 28 | @end 29 | 30 | @interface BaseViewController () 31 | 32 | @end 33 | 34 | @implementation BaseViewController 35 | 36 | - (void)viewWillAppear:(BOOL)animated { 37 | [self updateNavigationBarDisplay]; 38 | 39 | [super viewWillAppear:animated]; 40 | } 41 | 42 | - (void)updateNavigationBarDisplay { 43 | MLNavigationBarConfig *config = self.navigationBarConfig; 44 | 45 | //if config is nil, reset to default, please change logic below with your own default 46 | 47 | [self.navigationController.navigationBar setBarTintColor:config.barTintColor]; 48 | 49 | [self.navigationController.navigationBar setBackgroundImage:kImageWithColor(config.barBackgroundImageColor) forBarMetrics:UIBarMetricsDefault]; 50 | if (config) { 51 | [self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName:config.titleColor}]; 52 | }else{ 53 | [self.navigationController.navigationBar setTitleTextAttributes:nil]; 54 | } 55 | 56 | for (UIBarButtonItem *item in self.navigationItem.leftBarButtonItems) { 57 | item.tintColor = config.itemColor; 58 | } 59 | 60 | for (UIBarButtonItem *item in self.navigationItem.rightBarButtonItems) { 61 | item.tintColor = config.itemColor; 62 | } 63 | //back button tint color 64 | self.navigationController.navigationBar.tintColor = config.itemColor; 65 | 66 | //alpha 67 | self.navigationController.navigationBar.ml_backgroundAlpha = config?config.backgroundAlpha:1.0f; 68 | 69 | //shadow hidden 70 | self.navigationController.navigationBar.ml_backgroundShadowView.hidden = config?!config.showShadowImage:NO; 71 | 72 | //other default 73 | 74 | //Please set translucent to YES,. 75 | //If it's YES, the self.view.frame.origin.y would be zero. 76 | //Or if ml_backgroundAlpha<1.0f, the views below it would be displayed. 77 | [self.navigationController.navigationBar setTranslucent:YES]; 78 | 79 | //update status bar style 80 | [self setNeedsStatusBarAppearanceUpdate]; 81 | } 82 | 83 | @end 84 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MLNavigationBarTransition [中文介绍](https://github.com/molon/MLNavigationBarTransition#中文介绍) 2 | ## Screenshot 3 | ![MLNavigationBarTransition](https://raw.githubusercontent.com/molon/MLNavigationBarTransition/master/snapshot.gif) 4 | 5 | ## Introduction 6 | 7 | Inspired by [KMNavigationBarTransition](https://github.com/MoZhouqi/KMNavigationBarTransition). First of all, this statement and thanks. But due to individual details can not meet personal preferences, with a completely different violent way to re-build a wheel. 8 | 9 | - Only support for iOS7+. 10 | - If two pages have different navigation bar background effect, an overlay effect not like official will appear. 11 | - If an overlay effect appears or navigation bar's `alpha` less than `1.0f`, the shadow border will certainly be displayed in the middle. Regardless of whether the ` translucent` of the navigation bar is `YES`. 12 | - If the two pages have exactly the same navigation bar background effect, official effect will appear. 13 | - If backButtons of two pages have different `tintColor`, a fade effect not like official will appear. 14 | - Fixed a bug that caused flicker when two pages have different `barTintColor` on iOS 8.2 or below. 15 | 16 | ### Addition Tips 17 | 18 | - Please do not set `navigationBarHidden` to` YES`(it has bugs). If you want to hide the navigation bar, use `self.navigationBar.ml_backgroundAlpha = 0.0f;` 19 | - If you want to hide the bottom shadow of the navigation bar, use `self.navigationController.navigationBar.ml_backgroundShadowView.hidden = YES` 20 | - Keep `translucent` as` YES` as far as possible, because if it is `NO`, the head of the page in the navigator will remain under the navigation bar, so if the navigation bar's `alpha` less than `1.0f`, will reveal views below, resulting in abnormal results. 21 | 22 | ### Disclaimer 23 | 1. This library uses unpublished api (non-private), please use it at your own risk, unpublished APIs do not have official compatibility commitments from iOS. 24 | 2. My application has been approved. It is possible that the AppStore will only prohibit the listing of applications that use private APIs and will not strictly treat unpublished APIs, but this is just my guess. 25 | 26 | ## 中文介绍 27 | 一直想做个类似微信转场里导航条效果的库,并且一直苦于SDK里`navigationBarHidden`为`YES`时候的BUG没能良好解决。 28 | 在发现了[KMNavigationBarTransition](https://github.com/MoZhouqi/KMNavigationBarTransition)之后得到灵感,首先对此表示声明以及感谢,但是由于个别细节无法满足个人喜好,就用了完全不一样的比较暴力的方式重新造了个轮子。 29 | 30 | - 只支持iOS7+ 31 | - 如果两个页面有不一样的导航条背景效果的话,转场时候将会出现导航条叠加的效果。(即使只有底部阴影条显示透明度不同这种细节,也会被认作不同) 32 | - 如果一个叠加效果显示了或者导航条背景有透明度,中间必定会显示阴影条,无论导航条的`translucent`是否为`YES`。 33 | - 如果两个页面具有完完全全一模一样的导航条背景效果,使用原生转场效果。 34 | - 如果两个页面的导航条返回按钮有不一样的`tintColor`,转场时候会有一个过渡效果,不会像原生那样立即就改变为目的`tintColor`。 35 | - 在iOS 8.2或以下系统,如果两个页面的`barTintColor`不一样之后会出现闪烁现象的BUG修复。 36 | - 对子页面的`view`没有任何侵入。 37 | 38 | ### 一些提示 39 | - 请不要设置`navigationBarHidden`为`YES`,如果想隐藏导航条,请使用`self.navigationBar.ml_backgroundAlpha = 0.0f;` 40 | - 如果想要隐藏导航条底部阴影条,请使用`self.navigationController.navigationBar.ml_backgroundShadowView.hidden = YES` 41 | - 尽量让`translucent`保持为`YES`,因为它若为`NO`,则导航器里的页面的头部会保持在导航条之下,这样的话,若对导航条背景设置透明度的话,就会透出下面的view,产生异常效果。 42 | 43 | ### 免责声明 44 | 1. 该库使用未发布的 api(非私有),使用请自担风险,未发布的 api 并没有获得 iOS 官方的兼容性承诺。 45 | 2. 我的应用程序已获得批准,有可能 AppStore 只会禁止使用了私有api的程序上架,不会严格对待未发布的 api,但这也只是我的猜测。 46 | -------------------------------------------------------------------------------- /Classes/MLNavigationBarTransitionDefine.h: -------------------------------------------------------------------------------- 1 | // 2 | // MLNavigationBarTransitionDefine.h 3 | // MLNavigationBarTransition 4 | // 5 | // Created by molon on 2016/11/30. 6 | // Copyright © 2016年 molon. All rights reserved. 7 | // 8 | 9 | #pragma once 10 | 11 | #import 12 | 13 | static inline BOOL mlnbt_doesIvarExistWithName(Class cls,NSString *ivarName) { 14 | if (!cls) { 15 | return NO; 16 | } 17 | 18 | unsigned int ivarCount = 0; 19 | Ivar *ivars = class_copyIvarList(cls, &ivarCount); 20 | if (ivars) { 21 | for (unsigned int i = 0; i < ivarCount; i++) { 22 | const char *name = ivar_getName(ivars[i]); 23 | if (name) { 24 | if ([[NSString stringWithUTF8String:name] isEqualToString:ivarName]) { 25 | free(ivars); 26 | return YES; 27 | } 28 | } 29 | } 30 | free(ivars); 31 | } 32 | return NO; 33 | } 34 | 35 | static inline BOOL mlnbt_doesPropertyExistWithName(Class cls,NSString *propertyName) { 36 | if (!cls) { 37 | return NO; 38 | } 39 | 40 | unsigned int propertyCount = 0; 41 | objc_property_t *properties = class_copyPropertyList(cls, &propertyCount); 42 | if (properties) { 43 | for (unsigned int i = 0; i < propertyCount; i++) { 44 | const char *name = property_getName(properties[i]); 45 | if (name) { 46 | if ([[NSString stringWithUTF8String:name] isEqualToString:propertyName]) { 47 | free(properties); 48 | return YES; 49 | } 50 | } 51 | } 52 | free(properties); 53 | } 54 | return NO; 55 | } 56 | 57 | static inline BOOL mlnbt_exchangeInstanceMethod(Class cls, SEL originalSel, SEL newSel) { 58 | if (!cls) { 59 | return NO; 60 | } 61 | 62 | Method originalMethod = class_getInstanceMethod(cls, originalSel); 63 | Method newMethod = class_getInstanceMethod(cls, newSel); 64 | if (!originalMethod || !newMethod) return NO; 65 | 66 | method_exchangeImplementations(originalMethod, 67 | newMethod); 68 | return YES; 69 | } 70 | 71 | #ifdef DEBUG 72 | #define MLNBT_NSASSERT(valid,format, ...) \ 73 | do { \ 74 | if (!(valid)) {\ 75 | NSString *astips = [NSString stringWithFormat:(format), ## __VA_ARGS__];\ 76 | NSLog(@"\n-------------\n%s:%d\n%@\nPlease contact molon. https://github.com/molon/MLNavigationBarTransition/issues\n-------------", __PRETTY_FUNCTION__, __LINE__, astips);\ 77 | NSAssert(NO, @"\n-------------\n%@\nPlease be assured that this assert will not be executed in the release environment!\nPlease contact molon. https://github.com/molon/MLNavigationBarTransition/issues\n-------------", astips);\ 78 | }\ 79 | }while(0) 80 | #else 81 | #define MLNBT_NSASSERT(valid,format, ...) \ 82 | do { \ 83 | if (!(valid)) {\ 84 | NSString *astips = [NSString stringWithFormat:(format), ## __VA_ARGS__];\ 85 | NSLog(@"\n-------------\n%s:%d\n%@\nPlease contact molon. https://github.com/molon/MLNavigationBarTransition/issues\n-------------", __PRETTY_FUNCTION__, __LINE__, astips);\ 86 | }\ 87 | }while(0) 88 | #endif 89 | 90 | #define MLNBT_SYNTH_DUMMY_CLASS(_name_) \ 91 | @interface MLNBT_SYNTH_DUMMY_CLASS ## _name_ : NSObject @end \ 92 | @implementation MLNBT_SYNTH_DUMMY_CLASS ## _name_ @end 93 | 94 | #define MLNBT_SYNTH_DYNAMIC_PROPERTY_OBJECT(_getter_, _setter_, _association_, _type_) \ 95 | - (void)_setter_ (_type_)object { \ 96 | [self willChangeValueForKey:@#_getter_]; \ 97 | objc_setAssociatedObject(self, _cmd, object, OBJC_ASSOCIATION_ ## _association_); \ 98 | [self didChangeValueForKey:@#_getter_]; \ 99 | } \ 100 | - (_type_)_getter_ { \ 101 | return objc_getAssociatedObject(self, @selector(_setter_)); \ 102 | } 103 | 104 | #define MLNBT_SYNTH_DYNAMIC_PROPERTY_CTYPE(_getter_, _setter_, _type_) \ 105 | - (void)_setter_ (_type_)object { \ 106 | [self willChangeValueForKey:@#_getter_]; \ 107 | NSValue *value = [NSValue value:&object withObjCType:@encode(_type_)]; \ 108 | objc_setAssociatedObject(self, _cmd, value, OBJC_ASSOCIATION_RETAIN); \ 109 | [self didChangeValueForKey:@#_getter_]; \ 110 | } \ 111 | - (_type_)_getter_ { \ 112 | _type_ cValue = { 0 }; \ 113 | NSValue *value = objc_getAssociatedObject(self, @selector(_setter_)); \ 114 | [value getValue:&cValue]; \ 115 | return cValue; \ 116 | } 117 | -------------------------------------------------------------------------------- /Example/MLNavigationBarTransition/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // MLNavigationBarTransition 4 | // 5 | // Created by molon on 2016/11/27. 6 | // Copyright © 2016年 molon. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "MLPickerButton.h" 11 | 12 | typedef NS_ENUM(NSUInteger, RowIndex) { 13 | RowIndexBarTintColor = 0, 14 | RowIndexBarBackgroundImageColor, 15 | RowIndexTitleColor, 16 | RowIndexItemColor, 17 | RowIndexShowShadowImage, 18 | RowIndexBackgroundAlpha, 19 | }; 20 | 21 | #define kRowCount 6 22 | #define kButtonTag 100 23 | 24 | #warning Demo code is ugly, please don't care about it too more. 25 | @interface ViewController () 26 | 27 | @property (nonatomic, strong) UITableView *tableView; 28 | 29 | @end 30 | 31 | @implementation ViewController 32 | 33 | - (void)viewDidLoad 34 | { 35 | [super viewDidLoad]; 36 | 37 | NSInteger index = [self.navigationController.viewControllers indexOfObject:self]; 38 | 39 | self.title = [NSString stringWithFormat:@"Title%ld",(long)index]; 40 | 41 | _tableView = ({ 42 | UITableView *tableView = [[UITableView alloc]init]; 43 | tableView.delegate = self; 44 | tableView.dataSource = self; 45 | tableView; 46 | }); 47 | 48 | _tableView.backgroundColor = self.view.backgroundColor = [UIColor colorWithRed:0.926 green:0.925 blue:0.946 alpha:1.000]; 49 | 50 | [self.view addSubview:_tableView]; 51 | 52 | NSString *text = [NSString stringWithFormat:@"Next%ld",(long)(index+1)]; 53 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:text style:UIBarButtonItemStylePlain target:self action:@selector(test)]; 54 | 55 | if (!_configs) { 56 | _configs = [@[ 57 | @"Red", 58 | @"None", 59 | @"Yellow", 60 | @"Yellow", 61 | @"YES", 62 | @"1.0", 63 | ]mutableCopy]; 64 | } 65 | else{ 66 | //simple test 67 | // if (index==2) { 68 | // _configs = [@[ 69 | // @"None", 70 | // @"None", 71 | // @"Black", 72 | // @"Black", 73 | // @"YES", 74 | // @"0.0", 75 | // ]mutableCopy]; 76 | // }else if (index==4) { 77 | // _configs = [@[ 78 | // @"Gray", 79 | // @"None", 80 | // @"White", 81 | // @"White", 82 | // @"YES", 83 | // @"1.0", 84 | // ]mutableCopy]; 85 | // }else if (index==5) { 86 | // _configs = [@[ 87 | // @"Red", 88 | // @"None", 89 | // @"Yellow", 90 | // @"Yellow", 91 | // @"YES", 92 | // @"1.0", 93 | // ]mutableCopy]; 94 | // } 95 | } 96 | 97 | self.navigationBarConfig = [self barConfigWithConfigs:_configs]; 98 | } 99 | 100 | - (UIStatusBarStyle)preferredStatusBarStyle { 101 | //just for test 102 | if (self.navigationBarConfig.backgroundAlpha<0.5||(!self.navigationBarConfig.barTintColor&&!self.navigationBarConfig.barBackgroundImageColor)) { 103 | return UIStatusBarStyleDefault; 104 | } 105 | return UIStatusBarStyleLightContent; 106 | } 107 | 108 | #pragma mark - event 109 | - (void)test 110 | { 111 | ViewController *vc = [ViewController new]; 112 | vc.configs = [_configs mutableCopy]; 113 | [self.navigationController pushViewController:vc animated:YES]; 114 | } 115 | 116 | #pragma mark - helper 117 | - (MLNavigationBarConfig*)barConfigWithConfigs:(NSArray*)configs { 118 | MLNavigationBarConfig *barConfig = [MLNavigationBarConfig new]; 119 | 120 | NSDictionary *map = @{ 121 | @"Gray":[UIColor colorWithRed:0.052 green:0.052 blue:0.057 alpha:1.000], 122 | @"Red":[UIColor colorWithRed:0.802 green:0.218 blue:0.203 alpha:1.000], 123 | @"Yellow":[UIColor colorWithRed:0.991 green:0.851 blue:0.627 alpha:1.000], 124 | @"White":[UIColor whiteColor], 125 | @"Black":[UIColor blackColor], 126 | }; 127 | 128 | 129 | barConfig.barTintColor = map[configs[RowIndexBarTintColor]]; 130 | barConfig.barBackgroundImageColor = map[configs[RowIndexBarBackgroundImageColor]]; 131 | barConfig.titleColor = map[configs[RowIndexTitleColor]]; 132 | barConfig.itemColor = map[configs[RowIndexItemColor]]; 133 | barConfig.showShadowImage = [configs[RowIndexShowShadowImage] isEqualToString:@"YES"]?YES:NO; 134 | barConfig.backgroundAlpha = [configs[RowIndexBackgroundAlpha] floatValue]; 135 | 136 | return barConfig; 137 | } 138 | 139 | #pragma mark - layout 140 | - (void)viewWillLayoutSubviews 141 | { 142 | [super viewWillLayoutSubviews]; 143 | 144 | self.tableView.frame = self.view.bounds; 145 | } 146 | 147 | #pragma mark - tableview 148 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 149 | { 150 | return 44.0f; 151 | } 152 | 153 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 154 | { 155 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 156 | 157 | if (indexPath.row==kRowCount) { 158 | self.navigationBarConfig = [self barConfigWithConfigs:_configs]; 159 | [self updateNavigationBarDisplay]; 160 | return; 161 | } 162 | 163 | UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 164 | MLPickerButton *button = (MLPickerButton *)[cell.contentView viewWithTag:kButtonTag]; 165 | NSString *currentValue = _configs[indexPath.row]; 166 | NSInteger index = [button.dataOfSingleComponentPicker indexOfObject:currentValue]; 167 | if (index!=NSNotFound) { 168 | [button.pickerView selectRow:index inComponent:0 animated:NO]; 169 | } 170 | [button touchUpInSide]; 171 | } 172 | 173 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 174 | { 175 | return kRowCount+1; 176 | } 177 | 178 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 179 | { 180 | if (indexPath.row==kRowCount) { 181 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UpdateCell"]; 182 | if (!cell) { 183 | cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"UpdateCell"]; 184 | cell.backgroundColor = cell.contentView.backgroundColor = [UIColor clearColor]; 185 | } 186 | cell.textLabel.text = @"Update Current NavigationBar Display"; 187 | return cell; 188 | } 189 | 190 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([UITableViewCell class])]; 191 | if (!cell) { 192 | cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:NSStringFromClass([UITableViewCell class])]; 193 | cell.backgroundColor = cell.contentView.backgroundColor = [UIColor clearColor]; 194 | 195 | //create picker button 196 | MLPickerButton *button = [MLPickerButton buttonWithType:UIButtonTypeCustom]; 197 | button.frame = CGRectZero; 198 | button.delegate = self; 199 | button.tag = kButtonTag; 200 | [cell.contentView addSubview:button]; 201 | } 202 | 203 | cell.textLabel.text = @[@"BarTintColor",@"BackgroundImageColor",@"TitleColor",@"ItemColor",@"ShowShadowImage",@"BackgroundAlpha",@"BackgroundHeight"][indexPath.row]; 204 | cell.detailTextLabel.text = _configs[indexPath.row]; 205 | 206 | MLPickerButton *button = [cell.contentView viewWithTag:kButtonTag]; 207 | button.pickerTitle = cell.textLabel.text; 208 | button.userInfo = @(indexPath.row); 209 | switch (indexPath.row) { 210 | case RowIndexBarTintColor: 211 | button.dataOfSingleComponentPicker = @[@"None",@"Gray",@"Red"]; 212 | break; 213 | case RowIndexBarBackgroundImageColor: 214 | button.dataOfSingleComponentPicker = @[@"None",@"Gray",@"Red"]; 215 | break; 216 | case RowIndexTitleColor: 217 | button.dataOfSingleComponentPicker = @[@"White",@"Black",@"Yellow"]; 218 | break; 219 | case RowIndexItemColor: 220 | button.dataOfSingleComponentPicker = @[@"White",@"Black",@"Yellow"]; 221 | break; 222 | case RowIndexShowShadowImage: 223 | button.dataOfSingleComponentPicker = @[@"YES",@"NO"]; 224 | break; 225 | case RowIndexBackgroundAlpha: 226 | button.dataOfSingleComponentPicker = @[@"1.0",@"0.8",@"0.5",@"0.0"]; 227 | break; 228 | default: 229 | break; 230 | } 231 | 232 | return cell; 233 | } 234 | 235 | #pragma mark - event 236 | - (void)doneWithPickerButton:(MLPickerButton*)pickerButton { 237 | NSInteger index = [pickerButton.pickerView selectedRowInComponent:0]; 238 | NSString *colorString = pickerButton.dataOfSingleComponentPicker[index]; 239 | _configs[[pickerButton.userInfo integerValue]] = colorString; 240 | 241 | [self.tableView reloadData]; 242 | } 243 | 244 | @end 245 | -------------------------------------------------------------------------------- /Example/MLNavigationBarTransition/MLPickerButton/MLPickerButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // MLPickerButton.m 3 | // InventoryTool 4 | // 5 | // Created by molon on 14-1-22. 6 | // Copyright (c) 2014年 Molon. All rights reserved. 7 | // 8 | 9 | #import "MLPickerButton.h" 10 | 11 | #define kBlackOverlayViewAnimateDuration .25f 12 | @interface MLPickerButton() 13 | 14 | @property(strong,nonatomic,readwrite) UIToolbar *inputAccessoryView; 15 | @property(strong,nonatomic,readwrite) UIPickerView *inputView; 16 | @property(nonatomic,strong) UIView *blackOverlayView; 17 | @property(nonatomic,strong) UILabel *pickerTitleLabel; 18 | 19 | @end 20 | 21 | @implementation MLPickerButton 22 | 23 | - (id)initWithFrame:(CGRect)frame 24 | { 25 | self = [super initWithFrame:frame]; 26 | if (self) { 27 | // Initialization code 28 | [self setUp]; 29 | } 30 | return self; 31 | } 32 | 33 | - (id)initWithCoder:(NSCoder *)aDecoder 34 | { 35 | self = [super initWithCoder:aDecoder]; 36 | if (self) { 37 | [self setUp]; 38 | } 39 | return self; 40 | } 41 | 42 | - (void)setUp 43 | { 44 | //添加一个点击可成为第一响应者的Target 45 | [super addTarget:self action:@selector(defaultTarget) forControlEvents:UIControlEventTouchUpInside]; 46 | } 47 | 48 | //覆盖了,不让用户外部可以添加Target 49 | - (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents 50 | { 51 | return; 52 | } 53 | 54 | #pragma mark - input 55 | - (UIToolbar *)inputAccessoryView 56 | { 57 | if(!_inputAccessoryView){ 58 | UIToolbar *toolBar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, self.inputView.frame.size.width, 44)]; 59 | 60 | NSString *title = @"取消"; 61 | if (self.delegate&&[self.delegate respondsToSelector:@selector(customCancelTitle)]) { 62 | title = [self.delegate customCancelTitle]; 63 | } 64 | UIBarButtonItem *left = [[UIBarButtonItem alloc]initWithTitle:title style:UIBarButtonItemStyleDone target:self action:@selector(cancel)]; 65 | UIBarButtonItem * spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil]; 66 | UIBarButtonItem *right = [[UIBarButtonItem alloc]initWithTitle:@"完成" style:UIBarButtonItemStyleDone target:self action:@selector(done)]; 67 | 68 | if (self.dontDisplayDimmingView) { 69 | toolBar.items = @[spaceItem,right]; 70 | }else{ 71 | toolBar.items = @[left,spaceItem,right]; 72 | } 73 | 74 | toolBar.backgroundColor = [UIColor whiteColor]; 75 | _inputAccessoryView = toolBar; 76 | } 77 | return _inputAccessoryView; 78 | } 79 | 80 | - (UIPickerView *)inputView 81 | { 82 | if(!_inputView) 83 | { 84 | UIPickerView *pickView = [[UIPickerView alloc]init]; 85 | pickView.showsSelectionIndicator = YES; 86 | pickView.backgroundColor = [UIColor whiteColor]; 87 | pickView.delegate = self; 88 | pickView.dataSource = self; 89 | _inputView = pickView; 90 | } 91 | return _inputView; 92 | } 93 | 94 | #pragma mark - other view 95 | - (UILabel*)pickerTitleLabel 96 | { 97 | if (!_pickerTitleLabel) { 98 | UILabel *label = [[UILabel alloc]init]; 99 | label.backgroundColor = [UIColor clearColor]; 100 | label.textColor = [UIColor blackColor]; 101 | label.textAlignment = NSTextAlignmentCenter; 102 | 103 | [self.inputAccessoryView addSubview:label]; 104 | 105 | _pickerTitleLabel = label; 106 | 107 | _pickerTitleLabel.frame = self.inputAccessoryView.bounds; 108 | } 109 | return _pickerTitleLabel; 110 | } 111 | 112 | - (void)layoutSubviews 113 | { 114 | [super layoutSubviews]; 115 | 116 | self.pickerTitleLabel.frame = self.inputAccessoryView.bounds; 117 | } 118 | 119 | #pragma mark default target 120 | - (void)defaultTarget 121 | { 122 | if (self.delegate&& [self.delegate respondsToSelector:@selector(shouldBecomeFirstResponderWithPickerButton:)]) { 123 | if (![self.delegate shouldBecomeFirstResponderWithPickerButton:self]) { 124 | return; 125 | } 126 | } 127 | 128 | if (!self.pickerDelegate||!self.pickerDataSource) { 129 | self.inputView.dataSource = self; 130 | self.inputView.delegate = self; 131 | }else{ 132 | self.inputView.dataSource = self.pickerDataSource; 133 | self.inputView.delegate = self.pickerDelegate; 134 | } 135 | [self becomeFirstResponder]; 136 | } 137 | 138 | #pragma mark - setter and getter 139 | - (void)setDataOfSingleComponentPicker:(NSArray *)dataOfSingleComponentPicker 140 | { 141 | _dataOfSingleComponentPicker = dataOfSingleComponentPicker; 142 | 143 | [self.pickerView reloadAllComponents]; 144 | } 145 | 146 | - (void)setPickerTitle:(NSString *)pickerTitle 147 | { 148 | _pickerTitle = [pickerTitle copy]; 149 | 150 | self.pickerTitleLabel.text = pickerTitle; 151 | } 152 | 153 | - (UIPickerView*)pickerView 154 | { 155 | return self.inputView; 156 | } 157 | 158 | - (void)setDontDisplayDimmingView:(BOOL)dontDisplayDimmingView 159 | { 160 | _dontDisplayDimmingView = dontDisplayDimmingView; 161 | 162 | self.inputAccessoryView = nil; 163 | } 164 | 165 | #pragma mark toolBar event 166 | -(void)cancel 167 | { 168 | if (self.delegate&&[self.delegate respondsToSelector:@selector(customClickCancle)]) { 169 | [self.delegate customClickCancle]; 170 | }else{ 171 | [self resignFirstResponder]; 172 | } 173 | } 174 | 175 | - (void)done 176 | { 177 | if (self.delegate&&[self.delegate respondsToSelector:@selector(doneWithPickerButton:)]) { 178 | [self.delegate doneWithPickerButton:self]; 179 | } 180 | 181 | [self resignFirstResponder]; 182 | } 183 | 184 | #pragma mark - responder and blackOverlayView 185 | - (BOOL) canBecomeFirstResponder { 186 | return YES; 187 | } 188 | 189 | - (BOOL)becomeFirstResponder 190 | { 191 | if ([self isFirstResponder]) { 192 | return YES; 193 | } 194 | BOOL result = [super becomeFirstResponder]; 195 | if (result) { 196 | if (self.blackOverlayView) { 197 | [self.blackOverlayView removeFromSuperview]; 198 | self.blackOverlayView = nil; 199 | } 200 | if (!self.dontDisplayDimmingView) { 201 | //添加一个蒙版黑色View 202 | UIWindow* window = [UIApplication sharedApplication].delegate.window; 203 | UIView *blackView = [[UIView alloc]initWithFrame:window.bounds]; 204 | blackView.backgroundColor = [UIColor blackColor]; 205 | blackView.userInteractionEnabled = YES; 206 | [window addSubview:self.blackOverlayView = blackView]; 207 | 208 | //对其添加点击事件 209 | UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]init]; 210 | tapGesture.numberOfTapsRequired = 1; 211 | tapGesture.numberOfTouchesRequired = 1; 212 | [tapGesture addTarget:self action:@selector(tapBlackOverlayViewWithTapGesture:)]; 213 | [self.blackOverlayView addGestureRecognizer:tapGesture]; 214 | 215 | blackView.layer.opacity = 0.09f; 216 | [UIView animateWithDuration:kBlackOverlayViewAnimateDuration animations:^{ 217 | blackView.layer.opacity = 0.30f; 218 | }]; 219 | } 220 | 221 | if (self.delegate&&[self.delegate respondsToSelector:@selector(becomeFirstResponderWithPickerButton:)]) { 222 | [self.delegate becomeFirstResponderWithPickerButton:self]; 223 | } 224 | 225 | } 226 | return result; 227 | } 228 | 229 | - (BOOL)resignFirstResponder 230 | { 231 | BOOL result = [super resignFirstResponder]; 232 | if (result) { 233 | [self hideBlackOverlayView]; 234 | 235 | if (self.delegate&&[self.delegate respondsToSelector:@selector(resignFirstResponderWithPickerButton:)]) { 236 | [self.delegate resignFirstResponderWithPickerButton:self]; 237 | } 238 | } 239 | return result; 240 | } 241 | 242 | #pragma mark - tap event 243 | - (void)tapBlackOverlayViewWithTapGesture:(UITapGestureRecognizer*)tapGesture 244 | { 245 | [self resignFirstResponder]; 246 | } 247 | 248 | 249 | #pragma mark - picker datasource 250 | - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView 251 | { 252 | return 1; 253 | } 254 | 255 | - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component 256 | { 257 | return self.dataOfSingleComponentPicker.count; 258 | } 259 | 260 | #pragma mark - picker delegate 261 | - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component 262 | { 263 | return self.dataOfSingleComponentPicker[row]; 264 | } 265 | 266 | - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component 267 | { 268 | if (self.delegate&&[self.delegate respondsToSelector:@selector(didSelectWithPickerButton:)]) { 269 | [self.delegate didSelectWithPickerButton:self]; 270 | } 271 | } 272 | 273 | #pragma mark - touchUpInSide 274 | - (void)touchUpInSide 275 | { 276 | [self defaultTarget]; 277 | } 278 | 279 | #pragma mark - other 280 | - (void)dealloc 281 | { 282 | [self hideBlackOverlayView]; 283 | } 284 | 285 | - (void)hideBlackOverlayView 286 | { 287 | if (self.blackOverlayView) { 288 | UIView *blackOverlayView = self.blackOverlayView; 289 | self.blackOverlayView = nil; 290 | [UIView animateWithDuration:kBlackOverlayViewAnimateDuration animations:^{ 291 | blackOverlayView.layer.opacity = 0.01f; 292 | } completion:^(BOOL finished) { 293 | [blackOverlayView removeFromSuperview]; 294 | }]; 295 | } 296 | } 297 | @end 298 | -------------------------------------------------------------------------------- /Classes/UINavigationController+MLNavigationBarTransition.m: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationController+MLNavigationBarTransition.m 3 | // MLNavigationBarTransition 4 | // 5 | // Created by molon on 2016/11/28. 6 | // Copyright © 2016年 molon. All rights reserved. 7 | // 8 | 9 | #import "UINavigationController+MLNavigationBarTransition.h" 10 | #import "MLNavigationBarTransitionDefine.h" 11 | #import "UINavigationBar+MLNavigationBarTransition.h" 12 | #import "NSString+MLNavigationBarTransition_Encrypt.h" 13 | 14 | MLNBT_SYNTH_DUMMY_CLASS(UINavigationController_MLNavigationBarTransition) 15 | 16 | static inline UIImage *_mlnbt_snapshotWithView(UIView *view, BOOL afterUpdates) { 17 | UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0); 18 | [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:afterUpdates]; 19 | UIImage *snap = UIGraphicsGetImageFromCurrentImageContext(); 20 | UIGraphicsEndImageContext(); 21 | return snap; 22 | } 23 | 24 | #pragma mark - UIView(_MLNavigationBarTransition) 25 | @interface UIView (_MLNavigationBarTransition) 26 | 27 | @property (nonatomic, assign) BOOL _mlnbt_disableSettingHidden; 28 | 29 | @end 30 | 31 | @implementation UIView (_MLNavigationBarTransition) 32 | 33 | MLNBT_SYNTH_DYNAMIC_PROPERTY_CTYPE(_mlnbt_disableSettingHidden, set_mlnbt_disableSettingHidden:, BOOL) 34 | 35 | + (void)load { 36 | static dispatch_once_t onceToken; 37 | dispatch_once(&onceToken, ^{ 38 | mlnbt_exchangeInstanceMethod(self, @selector(setHidden:), @selector(_mlnbt_setHidden:)); 39 | }); 40 | } 41 | 42 | - (void)_mlnbt_setHidden:(BOOL)hidden { 43 | if (self._mlnbt_disableSettingHidden) { 44 | return; 45 | } 46 | 47 | [self _mlnbt_setHidden:hidden]; 48 | } 49 | 50 | @end 51 | 52 | #pragma mark - UINavigationController(MLNavigationBarTransition) 53 | 54 | @interface UINavigationController() 55 | 56 | @property (nonatomic, strong) UINavigationBar *_mlnbt_transitionFromBar; 57 | @property (nonatomic, strong) UINavigationBar *_mlnbt_transitionToBar; 58 | 59 | @end 60 | 61 | @implementation UINavigationController (MLNavigationBarTransition) 62 | 63 | + (void)load { 64 | static dispatch_once_t onceToken; 65 | dispatch_once(&onceToken, ^{ 66 | #pragma clang diagnostic push 67 | #pragma clang diagnostic ignored "-Wundeclared-selector" 68 | // NSLog(@"%@:%@",@"_startCustomTransition:",[@"_startCustomTransition:" mlnbt_EncryptString]); 69 | BOOL valid = /*mlnbt_exchangeInstanceMethod(self, @selector(setNavigationBarHidden:), @selector(_mlnbt_setNavigationBarHidden:))&& 70 | mlnbt_exchangeInstanceMethod(self, @selector(setNavigationBarHidden:animated:), @selector(_mlnbt_setNavigationBarHidden:animated:))&&*/ 71 | mlnbt_exchangeInstanceMethod(self,NSSelectorFromString([@"K3A0LKW0D3ImqT9gIUWuoaAcqTyiowb=" mlnbt_DecryptString]), @selector(_mlnbt_startCustomTransition:)); 72 | MLNBT_NSASSERT(valid, @"UINavigationController (MLNavigationBarTransition) is not valid now!"); 73 | #pragma clang diagnostic pop 74 | }); 75 | } 76 | 77 | #pragma mark - addition properties 78 | 79 | MLNBT_SYNTH_DYNAMIC_PROPERTY_OBJECT(_mlnbt_transitionFromBar, set_mlnbt_transitionFromBar:, RETAIN_NONATOMIC, UINavigationBar *) 80 | MLNBT_SYNTH_DYNAMIC_PROPERTY_OBJECT(_mlnbt_transitionToBar, set_mlnbt_transitionToBar:, RETAIN_NONATOMIC, UINavigationBar *) 81 | 82 | #pragma mark - disable navigationBarHidden 83 | //- (void)_mlnbt_setNavigationBarHidden:(BOOL)navigationBarHidden { 84 | // NSLog(@"Please dont use `navigationBarHidden`,there are some bugs with it in iOS SDK. You can use `.navigationBar.ml_backgroundAlpha = 0.0f;`"); 85 | // [self _mlnbt_setNavigationBarHidden:navigationBarHidden]; 86 | //} 87 | // 88 | //- (void)_mlnbt_setNavigationBarHidden:(BOOL)hidden animated:(BOOL)animated { 89 | // NSLog(@"Please dont use `navigationBarHidden`,there are some bugs with it in iOS SDK. You can use `.navigationBar.ml_backgroundAlpha = 0.0f;`"); 90 | // [self _mlnbt_setNavigationBarHidden:hidden animated:animated]; 91 | //} 92 | 93 | - (void)_mlnbt_startCustomTransition:(id)arg1 { 94 | UIColor *fromTintColor = nil; 95 | 96 | if ([self.transitionCoordinator isAnimated]) { 97 | UIView *containerView = [self.transitionCoordinator containerView]; 98 | if (containerView) { 99 | self._mlnbt_transitionFromBar = [self.navigationBar ml_replicantBarOfSameBackgroundEffectWithContainerView:containerView]; 100 | 101 | //maybe _mlnbt_transitionFromBar will be nil in `_mlnbt_startCustomTransition`, so we store it 102 | fromTintColor = self._mlnbt_transitionFromBar.tintColor; 103 | 104 | //back indicator fade out animation 105 | UIView *backIndicatorView = self.navigationBar.ml_backIndicatorView; 106 | if (backIndicatorView) { 107 | //Because `snapshotViewAfterScreenUpdates:` has some bugs, we abandon it 108 | // UIView *backIndicatorSnapshotView = [backIndicatorView snapshotViewAfterScreenUpdates:NO]; 109 | UIImage *snapshot = _mlnbt_snapshotWithView(backIndicatorView,NO); 110 | if (snapshot) { 111 | UIImageView *backIndicatorSnapshotView = [[UIImageView alloc]initWithImage:snapshot]; 112 | backIndicatorSnapshotView.alpha = backIndicatorView.alpha; 113 | 114 | backIndicatorSnapshotView.frame = backIndicatorView.bounds; 115 | [backIndicatorView addSubview:backIndicatorSnapshotView]; 116 | 117 | [self.transitionCoordinator animateAlongsideTransition:^(id _Nonnull context) { 118 | backIndicatorSnapshotView.alpha = 0.0f; 119 | } completion:^(id _Nonnull context) { 120 | [backIndicatorSnapshotView removeFromSuperview]; 121 | }]; 122 | } 123 | } 124 | 125 | //backButtonLabel fade out animation 126 | UILabel *backButtonLabel = self.navigationBar.ml_backButtonLabel; 127 | if (backButtonLabel) { 128 | backButtonLabel.textColor = fromTintColor; 129 | 130 | UIImage *snapshot = _mlnbt_snapshotWithView(backButtonLabel,NO); 131 | if (snapshot) { 132 | UIImageView *backButtonLabelSnapshotView = [[UIImageView alloc]initWithImage:snapshot]; 133 | backButtonLabelSnapshotView.alpha = backButtonLabel.alpha; 134 | 135 | backButtonLabelSnapshotView.frame = backButtonLabel.bounds; 136 | [backButtonLabel addSubview:backButtonLabelSnapshotView]; 137 | 138 | [self.transitionCoordinator animateAlongsideTransition:^(id _Nonnull context) { 139 | backButtonLabelSnapshotView.alpha = 0.0f; 140 | } completion:^(id _Nonnull context) { 141 | [backButtonLabelSnapshotView removeFromSuperview]; 142 | }]; 143 | } 144 | } 145 | } 146 | } 147 | 148 | [self _mlnbt_startCustomTransition:arg1]; 149 | } 150 | 151 | @end 152 | 153 | #pragma mark - NSObject(MLNavigationBarTransition) 154 | 155 | @interface NSObject(MLNavigationBarTransition) 156 | @end 157 | 158 | @implementation NSObject(MLNavigationBarTransition) 159 | 160 | + (void)load { 161 | static dispatch_once_t onceToken; 162 | dispatch_once(&onceToken, ^{ 163 | // NSLog(@"%@:%@",@"_UINavigationParallaxTransition",[@"_UINavigationParallaxTransition" mlnbt_EncryptString]); 164 | Class cls = NSClassFromString([@"K1IWGzS2nJquqTyioyOupzSfoTS4IUWuoaAcqTyiot==" mlnbt_DecryptString]); 165 | 166 | BOOL valid = mlnbt_exchangeInstanceMethod(cls,@selector(animateTransition:),@selector(_mlnbt_animateTransition:))&& 167 | mlnbt_exchangeInstanceMethod(cls,@selector(animationEnded:),@selector(_mlnbt_animationEnded:)); 168 | MLNBT_NSASSERT(valid, @"NSObject(MLNavigationBarTransition) is not valid now! Please check it."); 169 | }); 170 | } 171 | 172 | #pragma mark - helper 173 | - (UIView*)_mlnbt_shadowBorderViewForUINavigationParallaxTransition { 174 | @try { 175 | // NSLog(@"%@:%@",@"_borderDimmingView",[@"_borderDimmingView" mlnbt_EncryptString]); 176 | UIView *dimmingView = [self valueForKey:[@"K2WipzEypxEcoJ1cozqJnJI3" mlnbt_DecryptString]]; 177 | if (dimmingView) { 178 | UIImageView *imageView = nil; 179 | for (UIView *v in dimmingView.subviews) { 180 | if ([v isKindOfClass:[UIImageView class]]) { 181 | imageView = (UIImageView *)v; 182 | break; 183 | } 184 | } 185 | return imageView; 186 | } 187 | } @catch (NSException *exception) { 188 | NSLog(@"%@",exception); 189 | MLNBT_NSASSERT(NO, @"_mlnbt_shadowBorderViewForUINavigationParallaxTransition is not valid"); 190 | } 191 | return nil; 192 | } 193 | 194 | - (UIView*)_mlnbt_containerFromViewForUINavigationParallaxTransition { 195 | @try { 196 | // NSLog(@"%@:%@",@"containerFromView",[@"containerFromView" mlnbt_EncryptString]); 197 | return [self valueForKey:[@"L29hqTScozIlEaWioIMcMKp=" mlnbt_DecryptString]]; 198 | } @catch (NSException *exception) { 199 | NSLog(@"%@",exception); 200 | MLNBT_NSASSERT(NO, @"`containerFromView` key of UINavigationParallaxTransition is not valid"); 201 | } 202 | return nil; 203 | } 204 | 205 | - (UIView*)_mlnbt_containerToViewForUINavigationParallaxTransition { 206 | @try { 207 | // NSLog(@"%@:%@",@"containerToView",[@"containerToView" mlnbt_EncryptString]); 208 | return [self valueForKey:[@"L29hqTScozIlIT9JnJI3" mlnbt_DecryptString]]; 209 | } @catch (NSException *exception) { 210 | NSLog(@"%@",exception); 211 | MLNBT_NSASSERT(NO, @"`containerToView` key of UINavigationParallaxTransition is not valid"); 212 | } 213 | return nil; 214 | } 215 | 216 | - (id)_mlnbt_transitionContextForUINavigationParallaxTransition { 217 | @try { 218 | // NSLog(@"%@:%@",@"transitionContext",[@"transitionContext" mlnbt_EncryptString]); 219 | return [self valueForKey:[@"qUWuoaAcqTyioxAioaEyrUD=" mlnbt_DecryptString]]; 220 | } @catch (NSException *exception) { 221 | NSLog(@"%@",exception); 222 | MLNBT_NSASSERT(NO, @"`transitionContext` key of UINavigationParallaxTransition is not valid"); 223 | } 224 | return nil; 225 | } 226 | 227 | #pragma mark - hook 228 | - (void)_mlnbt_animateTransition:(id)transitionContext { 229 | UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; 230 | UINavigationController *navigationController = fromVC.navigationController; 231 | 232 | //if no _mlnbt_transitionFromBar, dont need continue 233 | if (!navigationController||!navigationController._mlnbt_transitionFromBar||![navigationController.transitionCoordinator isAnimated]) { 234 | navigationController._mlnbt_transitionFromBar = nil; 235 | [self _mlnbt_animateTransition:transitionContext]; 236 | return; 237 | } 238 | 239 | //transitionToBar, `viewWillAppear` of toVC has excuted now. 240 | //to bar 241 | UIView *containerView = [transitionContext containerView]; 242 | if (containerView) { 243 | navigationController._mlnbt_transitionToBar = [navigationController.navigationBar ml_replicantBarOfSameBackgroundEffectWithContainerView:containerView]; 244 | } 245 | 246 | //containerViews 247 | UIView *containerFromView = [self _mlnbt_containerFromViewForUINavigationParallaxTransition]; 248 | UIView *containerToView = [self _mlnbt_containerToViewForUINavigationParallaxTransition]; 249 | 250 | //if cant get these, just return 251 | if (!navigationController._mlnbt_transitionToBar||!containerFromView||!containerToView) { 252 | navigationController._mlnbt_transitionFromBar = nil; 253 | navigationController._mlnbt_transitionToBar = nil; 254 | 255 | [self _mlnbt_animateTransition:transitionContext]; 256 | return; 257 | } 258 | 259 | //shadow border should be short or not 260 | BOOL shortShadowBorder = NO; 261 | 262 | BOOL sameBackgroundEffect = [navigationController._mlnbt_transitionFromBar ml_isSameBackgroundEffectToNavigationBar:navigationController._mlnbt_transitionToBar]; 263 | if (!sameBackgroundEffect) { 264 | navigationController.navigationBar.ml_backgroundView.hidden = YES; 265 | navigationController.navigationBar.ml_backgroundView._mlnbt_disableSettingHidden = YES; 266 | 267 | [containerFromView addSubview:navigationController._mlnbt_transitionFromBar]; 268 | [containerToView addSubview:navigationController._mlnbt_transitionToBar]; 269 | }else{ 270 | //if alpha not equal with 1.0f, show long shadow border 271 | if (navigationController._mlnbt_transitionFromBar.ml_backgroundAlpha*navigationController._mlnbt_transitionFromBar.alpha>=0.999f) { 272 | shortShadowBorder = YES; 273 | } 274 | 275 | navigationController._mlnbt_transitionFromBar = nil; 276 | navigationController._mlnbt_transitionToBar = nil; 277 | } 278 | 279 | [self _mlnbt_animateTransition:transitionContext]; 280 | 281 | if (!shortShadowBorder) { 282 | UIView *shadowBorderView = [self _mlnbt_shadowBorderViewForUINavigationParallaxTransition]; 283 | CGPoint origin = [shadowBorderView convertPoint:CGPointZero toView:containerToView]; 284 | shadowBorderView.frame = CGRectMake(shadowBorderView.frame.origin.x, shadowBorderView.frame.origin.y-origin.y, shadowBorderView.frame.size.width, shadowBorderView.frame.size.height+origin.y); 285 | } 286 | } 287 | 288 | - (void)_mlnbt_animationEnded:(BOOL)transitionCompleted { 289 | [self _mlnbt_animationEnded:transitionCompleted]; 290 | 291 | UINavigationController *navigationController = nil; 292 | 293 | id transitionContext = [self _mlnbt_transitionContextForUINavigationParallaxTransition]; 294 | if (transitionContext) { 295 | UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; 296 | navigationController = toVC.navigationController; 297 | if (!navigationController) { 298 | navigationController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].navigationController; 299 | } 300 | } 301 | 302 | if (!navigationController) { 303 | return; 304 | } 305 | navigationController.navigationBar.ml_backgroundView._mlnbt_disableSettingHidden = NO; 306 | 307 | //fix a bug below 8.3 308 | if (navigationController.navigationBar.ml_backgroundView.hidden) { 309 | if (!transitionCompleted&&[UIDevice currentDevice].systemVersion.doubleValue<8.3f) { 310 | UIColor *barTintColor = navigationController.navigationBar.barTintColor; 311 | navigationController.navigationBar.barTintColor = nil; 312 | navigationController.navigationBar.barTintColor = barTintColor; 313 | } 314 | 315 | navigationController.navigationBar.ml_backgroundView.hidden = NO; 316 | } 317 | 318 | [navigationController._mlnbt_transitionFromBar removeFromSuperview]; 319 | [navigationController._mlnbt_transitionToBar removeFromSuperview]; 320 | navigationController._mlnbt_transitionFromBar = nil; 321 | navigationController._mlnbt_transitionToBar = nil; 322 | } 323 | 324 | @end 325 | -------------------------------------------------------------------------------- /Classes/UINavigationBar+MLNavigationBarTransition.m: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationBar+MLNavigationBarTransition.m 3 | // MLNavigationBarTransition 4 | // 5 | // Created by molon on 2016/11/29. 6 | // Copyright © 2016年 molon. All rights reserved. 7 | // 8 | 9 | #import "UINavigationBar+MLNavigationBarTransition.h" 10 | #import "MLNavigationBarTransitionDefine.h" 11 | #import "NSString+MLNavigationBarTransition_Encrypt.h" 12 | 13 | MLNBT_SYNTH_DUMMY_CLASS(UINavigationBar_MLNavigationBarTransition) 14 | 15 | @interface NSObject(_MLNavigationBarTransition) 16 | 17 | @end 18 | 19 | @implementation NSObject(_MLNavigationBarTransition) 20 | 21 | #define MLNBT_INIT_INV(_last_arg_, _return_) \ 22 | NSMethodSignature * sig = [self methodSignatureForSelector:sel]; \ 23 | if (!sig) { [self doesNotRecognizeSelector:sel]; return _return_; } \ 24 | NSInvocation *inv = [NSInvocation invocationWithMethodSignature:sig]; \ 25 | if (!inv) { [self doesNotRecognizeSelector:sel]; return _return_; } \ 26 | [inv setTarget:self]; \ 27 | [inv setSelector:sel]; \ 28 | va_list args; \ 29 | va_start(args, _last_arg_); \ 30 | [NSObject mlnbt_setInv:inv withSig:sig andArgs:args]; \ 31 | va_end(args); 32 | 33 | - (id)mlnbt_performSelectorWithArgs:(SEL)sel, ...{ 34 | MLNBT_INIT_INV(sel, nil); 35 | [inv invoke]; 36 | return [NSObject mlnbt_getReturnFromInv:inv withSig:sig]; 37 | } 38 | 39 | #undef MLNBT_INIT_INV 40 | 41 | + (id)mlnbt_getReturnFromInv:(NSInvocation *)inv withSig:(NSMethodSignature *)sig { 42 | NSUInteger length = [sig methodReturnLength]; 43 | if (length == 0) return nil; 44 | 45 | char *type = (char *)[sig methodReturnType]; 46 | while (*type == 'r' || // const 47 | *type == 'n' || // in 48 | *type == 'N' || // inout 49 | *type == 'o' || // out 50 | *type == 'O' || // bycopy 51 | *type == 'R' || // byref 52 | *type == 'V') { // oneway 53 | type++; // cutoff useless prefix 54 | } 55 | 56 | #define return_with_number(_type_) \ 57 | do { \ 58 | _type_ ret; \ 59 | [inv getReturnValue:&ret]; \ 60 | return @(ret); \ 61 | } while (0) 62 | 63 | switch (*type) { 64 | case 'v': return nil; // void 65 | case 'B': return_with_number(bool); 66 | case 'c': return_with_number(char); 67 | case 'C': return_with_number(unsigned char); 68 | case 's': return_with_number(short); 69 | case 'S': return_with_number(unsigned short); 70 | case 'i': return_with_number(int); 71 | case 'I': return_with_number(unsigned int); 72 | case 'l': return_with_number(int); 73 | case 'L': return_with_number(unsigned int); 74 | case 'q': return_with_number(long long); 75 | case 'Q': return_with_number(unsigned long long); 76 | case 'f': return_with_number(float); 77 | case 'd': return_with_number(double); 78 | case 'D': { // long double 79 | long double ret; 80 | [inv getReturnValue:&ret]; 81 | return [NSNumber numberWithDouble:ret]; 82 | }; 83 | 84 | case '@': { // id 85 | id ret = nil; 86 | [inv getReturnValue:&ret]; 87 | return ret; 88 | }; 89 | 90 | case '#': { // Class 91 | Class ret = nil; 92 | [inv getReturnValue:&ret]; 93 | return ret; 94 | }; 95 | 96 | default: { // struct / union / SEL / void* / unknown 97 | const char *objCType = [sig methodReturnType]; 98 | char *buf = calloc(1, length); 99 | if (!buf) return nil; 100 | [inv getReturnValue:buf]; 101 | NSValue *value = [NSValue valueWithBytes:buf objCType:objCType]; 102 | free(buf); 103 | return value; 104 | }; 105 | } 106 | #undef return_with_number 107 | } 108 | 109 | + (void)mlnbt_setInv:(NSInvocation *)inv withSig:(NSMethodSignature *)sig andArgs:(va_list)args { 110 | NSUInteger count = [sig numberOfArguments]; 111 | for (int index = 2; index < count; index++) { 112 | char *type = (char *)[sig getArgumentTypeAtIndex:index]; 113 | while (*type == 'r' || // const 114 | *type == 'n' || // in 115 | *type == 'N' || // inout 116 | *type == 'o' || // out 117 | *type == 'O' || // bycopy 118 | *type == 'R' || // byref 119 | *type == 'V') { // oneway 120 | type++; // cutoff useless prefix 121 | } 122 | 123 | BOOL unsupportedType = NO; 124 | switch (*type) { 125 | case 'v': // 1: void 126 | case 'B': // 1: bool 127 | case 'c': // 1: char / BOOL 128 | case 'C': // 1: unsigned char 129 | case 's': // 2: short 130 | case 'S': // 2: unsigned short 131 | case 'i': // 4: int / NSInteger(32bit) 132 | case 'I': // 4: unsigned int / NSUInteger(32bit) 133 | case 'l': // 4: long(32bit) 134 | case 'L': // 4: unsigned long(32bit) 135 | { // 'char' and 'short' will be promoted to 'int'. 136 | int arg = va_arg(args, int); 137 | [inv setArgument:&arg atIndex:index]; 138 | } break; 139 | 140 | case 'q': // 8: long long / long(64bit) / NSInteger(64bit) 141 | case 'Q': // 8: unsigned long long / unsigned long(64bit) / NSUInteger(64bit) 142 | { 143 | long long arg = va_arg(args, long long); 144 | [inv setArgument:&arg atIndex:index]; 145 | } break; 146 | 147 | case 'f': // 4: float / CGFloat(32bit) 148 | { // 'float' will be promoted to 'double'. 149 | double arg = va_arg(args, double); 150 | float argf = arg; 151 | [inv setArgument:&argf atIndex:index]; 152 | } break; 153 | 154 | case 'd': // 8: double / CGFloat(64bit) 155 | { 156 | double arg = va_arg(args, double); 157 | [inv setArgument:&arg atIndex:index]; 158 | } break; 159 | 160 | case 'D': // 16: long double 161 | { 162 | long double arg = va_arg(args, long double); 163 | [inv setArgument:&arg atIndex:index]; 164 | } break; 165 | 166 | case '*': // char * 167 | case '^': // pointer 168 | { 169 | void *arg = va_arg(args, void *); 170 | [inv setArgument:&arg atIndex:index]; 171 | } break; 172 | 173 | case ':': // SEL 174 | { 175 | SEL arg = va_arg(args, SEL); 176 | [inv setArgument:&arg atIndex:index]; 177 | } break; 178 | 179 | case '#': // Class 180 | { 181 | Class arg = va_arg(args, Class); 182 | [inv setArgument:&arg atIndex:index]; 183 | } break; 184 | 185 | case '@': // id 186 | { 187 | id arg = va_arg(args, id); 188 | [inv setArgument:&arg atIndex:index]; 189 | } break; 190 | 191 | case '{': // struct 192 | { 193 | if (strcmp(type, @encode(CGPoint)) == 0) { 194 | CGPoint arg = va_arg(args, CGPoint); 195 | [inv setArgument:&arg atIndex:index]; 196 | } else if (strcmp(type, @encode(CGSize)) == 0) { 197 | CGSize arg = va_arg(args, CGSize); 198 | [inv setArgument:&arg atIndex:index]; 199 | } else if (strcmp(type, @encode(CGRect)) == 0) { 200 | CGRect arg = va_arg(args, CGRect); 201 | [inv setArgument:&arg atIndex:index]; 202 | } else if (strcmp(type, @encode(CGVector)) == 0) { 203 | CGVector arg = va_arg(args, CGVector); 204 | [inv setArgument:&arg atIndex:index]; 205 | } else if (strcmp(type, @encode(CGAffineTransform)) == 0) { 206 | CGAffineTransform arg = va_arg(args, CGAffineTransform); 207 | [inv setArgument:&arg atIndex:index]; 208 | } else if (strcmp(type, @encode(CATransform3D)) == 0) { 209 | CATransform3D arg = va_arg(args, CATransform3D); 210 | [inv setArgument:&arg atIndex:index]; 211 | } else if (strcmp(type, @encode(NSRange)) == 0) { 212 | NSRange arg = va_arg(args, NSRange); 213 | [inv setArgument:&arg atIndex:index]; 214 | } else if (strcmp(type, @encode(UIOffset)) == 0) { 215 | UIOffset arg = va_arg(args, UIOffset); 216 | [inv setArgument:&arg atIndex:index]; 217 | } else if (strcmp(type, @encode(UIEdgeInsets)) == 0) { 218 | UIEdgeInsets arg = va_arg(args, UIEdgeInsets); 219 | [inv setArgument:&arg atIndex:index]; 220 | } else { 221 | unsupportedType = YES; 222 | } 223 | } break; 224 | 225 | case '(': // union 226 | { 227 | unsupportedType = YES; 228 | } break; 229 | 230 | case '[': // array 231 | { 232 | unsupportedType = YES; 233 | } break; 234 | 235 | default: // what?! 236 | { 237 | unsupportedType = YES; 238 | } break; 239 | } 240 | 241 | if (unsupportedType) { 242 | // Try with some dummy type... 243 | 244 | NSUInteger size = 0; 245 | NSGetSizeAndAlignment(type, &size, NULL); 246 | 247 | #define case_size(_size_) \ 248 | else if (size <= 4 * _size_ ) { \ 249 | struct dummy { char tmp[4 * _size_]; }; \ 250 | struct dummy arg = va_arg(args, struct dummy); \ 251 | [inv setArgument:&arg atIndex:index]; \ 252 | } 253 | if (size == 0) { } 254 | case_size( 1) case_size( 2) case_size( 3) case_size( 4) 255 | case_size( 5) case_size( 6) case_size( 7) case_size( 8) 256 | case_size( 9) case_size(10) case_size(11) case_size(12) 257 | case_size(13) case_size(14) case_size(15) case_size(16) 258 | case_size(17) case_size(18) case_size(19) case_size(20) 259 | case_size(21) case_size(22) case_size(23) case_size(24) 260 | case_size(25) case_size(26) case_size(27) case_size(28) 261 | case_size(29) case_size(30) case_size(31) case_size(32) 262 | case_size(33) case_size(34) case_size(35) case_size(36) 263 | case_size(37) case_size(38) case_size(39) case_size(40) 264 | case_size(41) case_size(42) case_size(43) case_size(44) 265 | case_size(45) case_size(46) case_size(47) case_size(48) 266 | case_size(49) case_size(50) case_size(51) case_size(52) 267 | case_size(53) case_size(54) case_size(55) case_size(56) 268 | case_size(57) case_size(58) case_size(59) case_size(60) 269 | case_size(61) case_size(62) case_size(63) case_size(64) 270 | else { 271 | /* 272 | Larger than 256 byte?! I don't want to deal with this stuff up... 273 | Ignore this argument. 274 | */ 275 | struct dummy {char tmp;}; 276 | for (int i = 0; i < size; i++) va_arg(args, struct dummy); 277 | NSLog(@"performSelectorWithArgs unsupported type:%s (%lu bytes)", 278 | [sig getArgumentTypeAtIndex:index],(unsigned long)size); 279 | } 280 | #undef case_size 281 | 282 | } 283 | } 284 | } 285 | 286 | @end 287 | 288 | @implementation UINavigationBar (MLNavigationBarTransition) 289 | 290 | - (UIView*)_mlnbt_recursiveFindSubviewWithClassNames:(NSArray*)clsNames { 291 | UIView *curView = self; 292 | for (NSString *clsName in clsNames) { 293 | NSArray *subviews = [curView subviews]; 294 | curView = nil; 295 | for (UIView *v in subviews) { 296 | if ([v isKindOfClass:NSClassFromString(clsName)]) { 297 | curView = v; 298 | break; 299 | } 300 | } 301 | if (!curView) { 302 | return nil; 303 | } 304 | } 305 | return curView; 306 | } 307 | 308 | - (UIView*)ml_backIndicatorView { 309 | static NSString *ivarKey = nil; 310 | static dispatch_once_t onceToken; 311 | dispatch_once(&onceToken, ^{ 312 | // NSLog(@"%@:%@",@"_backIndicatorView",[@"_backIndicatorView" mlnbt_EncryptString]); 313 | NSArray *keys = @[[@"K2WuL2gWozEcL2S0o3WJnJI3" mlnbt_DecryptString]]; 314 | for (NSString *key in keys) { 315 | if (mlnbt_doesIvarExistWithName([self class], key)) { 316 | ivarKey = key; 317 | break; 318 | } 319 | } 320 | }); 321 | if (ivarKey) { 322 | return [self valueForKey:ivarKey]; 323 | } 324 | 325 | // MLNBT_NSASSERT(NO, @"ml_backIndicatorView is not valid"); 326 | // return nil; 327 | 328 | //in iOS11, we only can find it with view hierarchy 329 | // NSLog(@"%@:%@",@"_UINavigationBarContentView",[@"_UINavigationBarContentView" mlnbt_EncryptString]); 330 | // NSLog(@"%@:%@",@"_UIButtonBarButton",[@"_UIButtonBarButton" mlnbt_EncryptString]); 331 | // NSLog(@"%@:%@",@"_UIModernBarButton",[@"_UIModernBarButton" mlnbt_EncryptString]); 332 | NSArray *clsNames = @[[@"K1IWGzS2nJquqTyioxWupxAioaEyoaEJnJI3" mlnbt_DecryptString], 333 | [@"K1IWDaI0qT9hDzSlDaI0qT9h" mlnbt_DecryptString], 334 | [@"K1IWGJ9xMKWhDzSlDaI0qT9h" mlnbt_DecryptString]]; 335 | return [self _mlnbt_recursiveFindSubviewWithClassNames:clsNames]; 336 | } 337 | 338 | - (UILabel*)ml_backButtonLabel { 339 | UILabel *label = nil; 340 | 341 | if ([UIDevice currentDevice].systemVersion.doubleValue>=11.0f) { 342 | //in iOS11, we only can find it with view hierarchy 343 | // NSLog(@"%@:%@",@"_UINavigationBarContentView",[@"_UINavigationBarContentView" mlnbt_EncryptString]); 344 | // NSLog(@"%@:%@",@"_UIButtonBarButton",[@"_UIButtonBarButton" mlnbt_EncryptString]); 345 | // NSLog(@"%@:%@",@"_UIBackButtonContainerView",[@"_UIBackButtonContainerView" mlnbt_EncryptString]); 346 | // NSLog(@"%@:%@",@"_UIModernBarButton",[@"_UIModernBarButton" mlnbt_EncryptString]); 347 | // NSLog(@"%@:%@",@"UIButtonLabel",[@"UIButtonLabel" mlnbt_EncryptString]); 348 | NSArray *clsNames = @[[@"K1IWGzS2nJquqTyioxWupxAioaEyoaEJnJI3" mlnbt_DecryptString], 349 | [@"K1IWDaI0qT9hDzSlDaI0qT9h" mlnbt_DecryptString], 350 | [@"K1IWDzSwn0W1qUEioxAioaEunJ5ypyMcMKp=" mlnbt_DecryptString], 351 | [@"K1IWGJ9xMKWhDzSlDaI0qT9h" mlnbt_DecryptString], 352 | [@"IHyPqKE0o25ZLJWyoN==" mlnbt_DecryptString], 353 | ]; 354 | return (UILabel*)[self _mlnbt_recursiveFindSubviewWithClassNames:clsNames]; 355 | } 356 | 357 | @try { 358 | // NSLog(@"%@:%@",@"_backButtonView",[@"_backButtonView" mlnbt_EncryptString]); 359 | // NSLog(@"%@:%@",@"_label",[@"_label" mlnbt_EncryptString]); 360 | UIView *backButtonView = [self.backItem valueForKey:[@"K2WuL2gPqKE0o25JnJI3" mlnbt_DecryptString]]; 361 | label = [backButtonView valueForKey:[@"K2kuLzIf" mlnbt_DecryptString]]; 362 | } @catch (NSException *exception) { 363 | NSLog(@"%@",exception); 364 | MLNBT_NSASSERT(NO, @"ml_backButtonLabel is not valid"); 365 | } 366 | 367 | return label; 368 | } 369 | 370 | - (UIView*)ml_backgroundShadowView { 371 | for (UIView *subv in self.ml_backgroundView.subviews) { 372 | if ([subv isKindOfClass:[UIImageView class]]&&subv.bounds.size.height<=1.0f) { 373 | return subv; 374 | } 375 | } 376 | return nil; 377 | } 378 | 379 | - (UIView*)ml_backgroundView { 380 | static NSString *varKey = nil; 381 | static dispatch_once_t onceToken; 382 | dispatch_once(&onceToken, ^{ 383 | // NSLog(@"%@:%@",@"_barBackgroundView",[@"_barBackgroundView" mlnbt_EncryptString]); 384 | // NSLog(@"%@:%@",@"_backgroundView",[@"_backgroundView" mlnbt_EncryptString]); 385 | NSArray *keys = @[[@"K2WupxWuL2gapz91ozEJnJI3" mlnbt_DecryptString],[@"K2WuL2gapz91ozEJnJI3" mlnbt_DecryptString]]; 386 | for (NSString *key in keys) { 387 | if (mlnbt_doesIvarExistWithName([self class], key)) { 388 | varKey = key; 389 | break; 390 | } 391 | } 392 | 393 | if (!varKey) { 394 | //in iOS11, it is a property named `_backgroundView` 395 | keys = @[[@"K2WuL2gapz91ozEJnJI3" mlnbt_DecryptString]]; 396 | for (NSString *key in keys) { 397 | if (mlnbt_doesPropertyExistWithName([self class], key)) { 398 | varKey = key; 399 | break; 400 | } 401 | } 402 | } 403 | }); 404 | if (varKey) { 405 | return [self valueForKey:varKey]; 406 | } 407 | 408 | MLNBT_NSASSERT(NO, @"ml_backgroundView is not valid"); 409 | return nil; 410 | } 411 | 412 | - (UIImage*)ml_currentBackgroundImage { 413 | static NSString *varKey = nil; 414 | static dispatch_once_t onceToken; 415 | dispatch_once(&onceToken, ^{ 416 | // NSLog(@"%@:%@",@"_backgroundImage",[@"_backgroundImage" mlnbt_EncryptString]); 417 | NSArray *keys = @[[@"K2WuL2gapz91ozEWoJSaMD==" mlnbt_DecryptString]]; 418 | for (NSString *key in keys) { 419 | if (mlnbt_doesIvarExistWithName([self.ml_backgroundView class], key)) { 420 | varKey = key; 421 | break; 422 | } 423 | } 424 | if (!varKey) { 425 | // NSLog(@"%@:%@",@"_currentCustomBackground",[@"_currentCustomBackground" mlnbt_EncryptString]); 426 | //#pragma clang diagnostic push 427 | //#pragma clang diagnostic ignored "-Wundeclared-selector" 428 | NSString *selName = [@"K2A1paWyoaEQqKA0o21PLJAeM3WiqJ5x" mlnbt_DecryptString]; 429 | if (self.ml_backgroundView&&class_getInstanceMethod([self.ml_backgroundView class],NSSelectorFromString(selName))) { 430 | varKey = selName; 431 | } 432 | // if ([self.ml_backgroundView respondsToSelector:NSSelectorFromString(selName)]) { 433 | // varKey = selName; 434 | // } 435 | //#pragma clang diagnostic pop 436 | } 437 | }); 438 | if (varKey) { 439 | return [self.ml_backgroundView valueForKey:varKey]; 440 | } 441 | 442 | MLNBT_NSASSERT(NO, @"ml_currentBackgroundImage is not valid"); 443 | return nil; 444 | } 445 | 446 | - (CGFloat)ml_backgroundAlpha { 447 | CGFloat alpha = self.ml_backgroundView.alpha; 448 | // NSLog(@"%@:%@",@"_backgroundOpacity",[@"_backgroundOpacity" mlnbt_EncryptString]); 449 | SEL sel = NSSelectorFromString([@"K2WuL2gapz91ozECpTSwnKE5" mlnbt_DecryptString]); 450 | if (class_getInstanceMethod([UINavigationBar class], sel)) { 451 | @try { 452 | alpha = [[self mlnbt_performSelectorWithArgs:sel]doubleValue]; 453 | } @catch (NSException *exception) { 454 | alpha = self.ml_backgroundView.alpha; 455 | NSLog(@"backgroundOpacity of UINavigationBar is not exist now!"); 456 | } 457 | } 458 | return alpha; 459 | } 460 | 461 | - (void)setMl_backgroundAlpha:(CGFloat)ml_backgroundAlpha { 462 | self.ml_backgroundView.alpha = ml_backgroundAlpha; 463 | // NSLog(@"%@:%@",@"_setBackgroundOpacity:",[@"_setBackgroundOpacity:" mlnbt_EncryptString]); 464 | SEL sel = NSSelectorFromString([@"K3AyqRWuL2gapz91ozECpTSwnKE5Bt==" mlnbt_DecryptString]); 465 | if (class_getInstanceMethod([UINavigationBar class], sel)) { 466 | @try { 467 | [self mlnbt_performSelectorWithArgs:sel,ml_backgroundAlpha]; 468 | } @catch (NSException *exception) { 469 | NSLog(@"setBackgroundOpacity: of UINavigationBar is not exist now!"); 470 | } 471 | } 472 | } 473 | 474 | - (UINavigationBar*)ml_replicantBarOfSameBackgroundEffectWithContainerView:(UIView*)containerView { 475 | UINavigationBar *bar = [UINavigationBar new]; 476 | bar.tintColor = self.tintColor; 477 | bar.barStyle = self.barStyle; 478 | bar.shadowImage = self.shadowImage; 479 | 480 | //backgroundImage 481 | [bar setBackgroundImage:[self backgroundImageForBarMetrics:UIBarMetricsDefault] forBarMetrics:UIBarMetricsDefault]; 482 | [bar setBackgroundImage:[self backgroundImageForBarMetrics:UIBarMetricsCompact] forBarMetrics:UIBarMetricsCompact]; 483 | [bar setBackgroundImage:[self backgroundImageForBarMetrics:UIBarMetricsDefaultPrompt] forBarMetrics:UIBarMetricsDefaultPrompt]; 484 | [bar setBackgroundImage:[self backgroundImageForBarMetrics:UIBarMetricsCompactPrompt] forBarMetrics:UIBarMetricsCompactPrompt]; 485 | 486 | //frame 487 | CGRect frame = self.frame; 488 | if (containerView) { 489 | CGRect (^convertRectToViewOrWindowBlock)(UIView *fromView, CGRect rect, UIView *view) = ^(UIView *fromView, CGRect rect, UIView *view){ 490 | if (!view) { 491 | if ([fromView isKindOfClass:[UIWindow class]]) { 492 | return [((UIWindow *)fromView) convertRect:rect toWindow:nil]; 493 | } else { 494 | return [fromView convertRect:rect toView:nil]; 495 | } 496 | } 497 | 498 | UIWindow *from = [fromView isKindOfClass:[UIWindow class]] ? (id)fromView : fromView.window; 499 | UIWindow *to = [view isKindOfClass:[UIWindow class]] ? (id)view : view.window; 500 | if (!from || !to) return [fromView convertRect:rect toView:view]; 501 | if (from == to) return [fromView convertRect:rect toView:view]; 502 | rect = [fromView convertRect:rect toView:from]; 503 | rect = [to convertRect:rect fromWindow:from]; 504 | rect = [view convertRect:rect fromView:to]; 505 | return rect; 506 | }; 507 | 508 | frame = convertRectToViewOrWindowBlock(self.superview,self.frame,containerView); 509 | } 510 | 511 | if ([UIDevice currentDevice].systemVersion.doubleValue<8.3f) { 512 | //below iOS8.3, if only use barTintColor, maybe trigger a bug that display a white line leftside. 513 | //We fix it below 514 | if (!self.ml_currentBackgroundImage) { 515 | CGFloat offset = 1.0f/[UIScreen mainScreen].scale; 516 | frame.origin.x -= offset; 517 | frame.size.width += offset*2; 518 | } 519 | } 520 | 521 | //in iOS10, if barTintColor is nil, then the ml_backgroundShadowView would be nil. 522 | //It's not our expectation, so we set non-nil value first to ensure the ml_backgroundShadowView created inside. 523 | bar.barTintColor = [UIColor blackColor]; 524 | bar.frame = frame; 525 | bar.barTintColor = self.barTintColor; 526 | 527 | CGRect backgroundViewFrame = self.ml_backgroundView.frame; 528 | backgroundViewFrame.size.width = bar.frame.size.width; 529 | bar.ml_backgroundView.frame = backgroundViewFrame; 530 | 531 | //alpha 532 | bar.alpha = self.alpha; 533 | bar.ml_backgroundAlpha = self.ml_backgroundAlpha; 534 | 535 | //shadow image view alpha and hidden 536 | bar.ml_backgroundShadowView.alpha = self.ml_backgroundShadowView.alpha; 537 | bar.ml_backgroundShadowView.hidden = self.ml_backgroundShadowView.hidden; 538 | 539 | //_barPosition is important 540 | @try { 541 | // NSLog(@"%@:%@",@"_barPosition",[@"_barPosition" mlnbt_EncryptString]); 542 | [bar setValue:@(self.barPosition) forKey:[@"K2WupyOip2y0nJ9h" mlnbt_DecryptString]]; 543 | } @catch (NSException *exception) { 544 | NSLog(@"%@",exception); 545 | MLNBT_NSASSERT(NO, @"setting $barPosition is not valid"); 546 | return nil; 547 | } 548 | 549 | //translucent 550 | bar.translucent = self.translucent; 551 | 552 | return bar; 553 | } 554 | 555 | - (BOOL)ml_isSameBackgroundEffectToNavigationBar:(UINavigationBar*)navigationBar { 556 | if (!navigationBar) { 557 | return NO; 558 | } 559 | 560 | if (self.barStyle!=navigationBar.barStyle) { 561 | return NO; 562 | } 563 | 564 | if (!CGSizeEqualToSize(self.frame.size, navigationBar.frame.size)|| 565 | self.alpha!=navigationBar.alpha|| 566 | !CGSizeEqualToSize(self.ml_backgroundView.frame.size, navigationBar.ml_backgroundView.frame.size)|| 567 | self.ml_backgroundAlpha != navigationBar.ml_backgroundAlpha|| 568 | self.ml_backgroundShadowView.alpha != navigationBar.ml_backgroundShadowView.alpha|| 569 | self.ml_backgroundShadowView.hidden != navigationBar.ml_backgroundShadowView.hidden 570 | ) { 571 | return NO; 572 | } 573 | 574 | if (!((!self.shadowImage&&!navigationBar.shadowImage)||[self.shadowImage isEqual:navigationBar.shadowImage]||[UIImagePNGRepresentation(self.shadowImage) isEqual:UIImagePNGRepresentation(navigationBar.shadowImage)])) { 575 | return NO; 576 | } 577 | 578 | // //if backgroundImages equal, ignore barTintColor 579 | // UIImage *backgroundImage1 = self.ml_currentBackgroundImage; 580 | // UIImage *backgroundImage2 = navigationBar.ml_currentBackgroundImage; 581 | // if ([backgroundImage1 isEqual:backgroundImage2]||[UIImagePNGRepresentation(backgroundImage1) isEqual:UIImagePNGRepresentation(backgroundImage2)]) { 582 | // return YES; 583 | // } 584 | // 585 | // //if no backgroundImages, barTintColor should be cared 586 | // if (!backgroundImage1&&!backgroundImage2) { 587 | // if ((!self.barTintColor&&!navigationBar.barTintColor)||CGColorEqualToColor(self.barTintColor.CGColor, navigationBar.barTintColor.CGColor)) { 588 | // return YES; 589 | // } 590 | // } 591 | 592 | //sometimes(like iOS11) the the ml_currentBackgroundImage is not valid to compare now, so we use another way! 593 | __block BOOL allBackgroundImageNil = YES; 594 | BOOL (^imageEqualBlock)(UIImage *,UIImage *) = ^BOOL (UIImage *a,UIImage *b){ 595 | if (!a&&!b) { 596 | return YES; 597 | } 598 | allBackgroundImageNil = NO; 599 | 600 | if ([a isEqual:b]) { 601 | return YES; 602 | } 603 | if ([UIImagePNGRepresentation(a) isEqual:UIImagePNGRepresentation(b)]) { 604 | return YES; 605 | } 606 | return NO; 607 | }; 608 | 609 | if (imageEqualBlock([self backgroundImageForBarMetrics:UIBarMetricsDefault],[navigationBar backgroundImageForBarMetrics:UIBarMetricsDefault])&& 610 | imageEqualBlock([self backgroundImageForBarMetrics:UIBarMetricsCompact],[navigationBar backgroundImageForBarMetrics:UIBarMetricsCompact])&& 611 | imageEqualBlock([self backgroundImageForBarMetrics:UIBarMetricsDefaultPrompt],[navigationBar backgroundImageForBarMetrics:UIBarMetricsDefaultPrompt])&& 612 | imageEqualBlock([self backgroundImageForBarMetrics:UIBarMetricsCompactPrompt],[navigationBar backgroundImageForBarMetrics:UIBarMetricsCompactPrompt])) { 613 | if (allBackgroundImageNil) { 614 | //if all nil ,care about barTintColor 615 | if ((!self.barTintColor&&!navigationBar.barTintColor)||CGColorEqualToColor(self.barTintColor.CGColor, navigationBar.barTintColor.CGColor)) { 616 | return YES; 617 | } 618 | }else{ 619 | return YES; 620 | } 621 | } 622 | 623 | return NO; 624 | } 625 | 626 | + (void)load { 627 | static dispatch_once_t onceToken; 628 | dispatch_once(&onceToken, ^{ 629 | BOOL valid = mlnbt_exchangeInstanceMethod(self, @selector(hitTest:withEvent:), @selector(_mlnbt_hitTest:withEvent:)); 630 | if (!valid) { 631 | NSLog(@"Hook on UINavigationBar (MLNavigationBarTransition) is not valid now! Please check it."); 632 | } 633 | }); 634 | } 635 | 636 | - (UIView *)_mlnbt_hitTest:(CGPoint)point withEvent:(UIEvent *)event { 637 | UIView *r = [self _mlnbt_hitTest:point withEvent:event]; 638 | if (self.ml_backgroundView&&self.ml_backgroundAlpha==0.0f) { 639 | if ([r isEqual:self]||[r isEqual:self.ml_backgroundView]) { 640 | //Because although touching back button area, the r is always the bar. so we need do extra checking. 641 | @try { 642 | 643 | #pragma clang diagnostic push 644 | #pragma clang diagnostic ignored "-Warc-performSelector-leaks" 645 | // NSLog(@"%@->%@",@"_hasBackButton",[@"_hasBackButton" mlnbt_EncryptString]); 646 | // NSLog(@"%@->%@",@"_shouldPopForTouchAtPoint:",[@"_shouldPopForTouchAtPoint:" mlnbt_EncryptString]); 647 | BOOL hasBackButton = [[self mlnbt_performSelectorWithArgs:NSSelectorFromString([@"K2uup0WuL2gPqKE0o24=" mlnbt_DecryptString])]boolValue]; 648 | BOOL shouldPopForTouchAtPoint = [[self mlnbt_performSelectorWithArgs:NSSelectorFromString([@"K3Abo3IfMSOipRMipyEiqJAbDKEDo2yhqQb=" mlnbt_DecryptString]),point]boolValue]; 649 | #pragma clang diagnostic pop 650 | if (hasBackButton&&shouldPopForTouchAtPoint) { 651 | return r; 652 | } 653 | } @catch (NSException *exception) { 654 | NSLog(@"hasBackButton or shouldPopForTouchAtPoint of UINavigationBar is not exist now!"); 655 | return nil; 656 | } 657 | 658 | return nil; 659 | } 660 | } 661 | return r; 662 | } 663 | 664 | @end 665 | -------------------------------------------------------------------------------- /Example/MLNavigationBarTransition.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 36408A901DEEB59E005A3BCF /* MLPickerButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 36408A8F1DEEB59E005A3BCF /* MLPickerButton.m */; }; 11 | 36408A931DEEB5AC005A3BCF /* BaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 36408A921DEEB5AC005A3BCF /* BaseViewController.m */; }; 12 | 36408A961DEEBB78005A3BCF /* UINavigationController+StatusStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = 36408A951DEEBB78005A3BCF /* UINavigationController+StatusStyle.m */; }; 13 | 36CA158D1DEB2F3C000FE4CA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 36CA158C1DEB2F3C000FE4CA /* main.m */; }; 14 | 36CA15901DEB2F3C000FE4CA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 36CA158F1DEB2F3C000FE4CA /* AppDelegate.m */; }; 15 | 36CA15931DEB2F3C000FE4CA /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 36CA15921DEB2F3C000FE4CA /* ViewController.m */; }; 16 | 36CA15981DEB2F3C000FE4CA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 36CA15971DEB2F3C000FE4CA /* Assets.xcassets */; }; 17 | 36CA15A61DEB2F3C000FE4CA /* MLNavigationBarTransitionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 36CA15A51DEB2F3C000FE4CA /* MLNavigationBarTransitionTests.m */; }; 18 | 36CA15B11DEB2F3C000FE4CA /* MLNavigationBarTransitionUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 36CA15B01DEB2F3C000FE4CA /* MLNavigationBarTransitionUITests.m */; }; 19 | E18BA79285840357F43A6C8F /* libPods-MLNavigationBarTransition.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A7AFE07447FD546BD96FD3B9 /* libPods-MLNavigationBarTransition.a */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXContainerItemProxy section */ 23 | 36CA15A21DEB2F3C000FE4CA /* PBXContainerItemProxy */ = { 24 | isa = PBXContainerItemProxy; 25 | containerPortal = 36CA15801DEB2F3C000FE4CA /* Project object */; 26 | proxyType = 1; 27 | remoteGlobalIDString = 36CA15871DEB2F3C000FE4CA; 28 | remoteInfo = MLNavigationBarTransition; 29 | }; 30 | 36CA15AD1DEB2F3C000FE4CA /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = 36CA15801DEB2F3C000FE4CA /* Project object */; 33 | proxyType = 1; 34 | remoteGlobalIDString = 36CA15871DEB2F3C000FE4CA; 35 | remoteInfo = MLNavigationBarTransition; 36 | }; 37 | /* End PBXContainerItemProxy section */ 38 | 39 | /* Begin PBXFileReference section */ 40 | 36408A8E1DEEB59E005A3BCF /* MLPickerButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MLPickerButton.h; sourceTree = ""; }; 41 | 36408A8F1DEEB59E005A3BCF /* MLPickerButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MLPickerButton.m; sourceTree = ""; }; 42 | 36408A911DEEB5AC005A3BCF /* BaseViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BaseViewController.h; sourceTree = ""; }; 43 | 36408A921DEEB5AC005A3BCF /* BaseViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BaseViewController.m; sourceTree = ""; }; 44 | 36408A941DEEBB78005A3BCF /* UINavigationController+StatusStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UINavigationController+StatusStyle.h"; sourceTree = ""; }; 45 | 36408A951DEEBB78005A3BCF /* UINavigationController+StatusStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UINavigationController+StatusStyle.m"; sourceTree = ""; }; 46 | 36CA15881DEB2F3C000FE4CA /* MLNavigationBarTransition.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MLNavigationBarTransition.app; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | 36CA158C1DEB2F3C000FE4CA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 48 | 36CA158E1DEB2F3C000FE4CA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 49 | 36CA158F1DEB2F3C000FE4CA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 50 | 36CA15911DEB2F3C000FE4CA /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 51 | 36CA15921DEB2F3C000FE4CA /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 52 | 36CA15971DEB2F3C000FE4CA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 53 | 36CA159C1DEB2F3C000FE4CA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54 | 36CA15A11DEB2F3C000FE4CA /* MLNavigationBarTransitionTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MLNavigationBarTransitionTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 55 | 36CA15A51DEB2F3C000FE4CA /* MLNavigationBarTransitionTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MLNavigationBarTransitionTests.m; sourceTree = ""; }; 56 | 36CA15A71DEB2F3C000FE4CA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 57 | 36CA15AC1DEB2F3C000FE4CA /* MLNavigationBarTransitionUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MLNavigationBarTransitionUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | 36CA15B01DEB2F3C000FE4CA /* MLNavigationBarTransitionUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MLNavigationBarTransitionUITests.m; sourceTree = ""; }; 59 | 36CA15B21DEB2F3C000FE4CA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 60 | 65F9AA77249756739A9195CA /* Pods-MLNavigationBarTransition.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MLNavigationBarTransition.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MLNavigationBarTransition/Pods-MLNavigationBarTransition.debug.xcconfig"; sourceTree = ""; }; 61 | A7AFE07447FD546BD96FD3B9 /* libPods-MLNavigationBarTransition.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-MLNavigationBarTransition.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 62 | AAC1587612449FC10C91F9DC /* Pods-MLNavigationBarTransition.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MLNavigationBarTransition.release.xcconfig"; path = "Pods/Target Support Files/Pods-MLNavigationBarTransition/Pods-MLNavigationBarTransition.release.xcconfig"; sourceTree = ""; }; 63 | /* End PBXFileReference section */ 64 | 65 | /* Begin PBXFrameworksBuildPhase section */ 66 | 36CA15851DEB2F3C000FE4CA /* Frameworks */ = { 67 | isa = PBXFrameworksBuildPhase; 68 | buildActionMask = 2147483647; 69 | files = ( 70 | E18BA79285840357F43A6C8F /* libPods-MLNavigationBarTransition.a in Frameworks */, 71 | ); 72 | runOnlyForDeploymentPostprocessing = 0; 73 | }; 74 | 36CA159E1DEB2F3C000FE4CA /* Frameworks */ = { 75 | isa = PBXFrameworksBuildPhase; 76 | buildActionMask = 2147483647; 77 | files = ( 78 | ); 79 | runOnlyForDeploymentPostprocessing = 0; 80 | }; 81 | 36CA15A91DEB2F3C000FE4CA /* Frameworks */ = { 82 | isa = PBXFrameworksBuildPhase; 83 | buildActionMask = 2147483647; 84 | files = ( 85 | ); 86 | runOnlyForDeploymentPostprocessing = 0; 87 | }; 88 | /* End PBXFrameworksBuildPhase section */ 89 | 90 | /* Begin PBXGroup section */ 91 | 0C6516221AA25B429E5400DF /* Pods */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | 65F9AA77249756739A9195CA /* Pods-MLNavigationBarTransition.debug.xcconfig */, 95 | AAC1587612449FC10C91F9DC /* Pods-MLNavigationBarTransition.release.xcconfig */, 96 | ); 97 | name = Pods; 98 | sourceTree = ""; 99 | }; 100 | 36408A8D1DEEB59E005A3BCF /* MLPickerButton */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | 36408A8E1DEEB59E005A3BCF /* MLPickerButton.h */, 104 | 36408A8F1DEEB59E005A3BCF /* MLPickerButton.m */, 105 | ); 106 | path = MLPickerButton; 107 | sourceTree = ""; 108 | }; 109 | 36CA157F1DEB2F3C000FE4CA = { 110 | isa = PBXGroup; 111 | children = ( 112 | 36CA158A1DEB2F3C000FE4CA /* MLNavigationBarTransition */, 113 | 36CA15A41DEB2F3C000FE4CA /* MLNavigationBarTransitionTests */, 114 | 36CA15AF1DEB2F3C000FE4CA /* MLNavigationBarTransitionUITests */, 115 | 36CA15891DEB2F3C000FE4CA /* Products */, 116 | 0C6516221AA25B429E5400DF /* Pods */, 117 | 4F7434085BC70DB6F860091B /* Frameworks */, 118 | ); 119 | sourceTree = ""; 120 | }; 121 | 36CA15891DEB2F3C000FE4CA /* Products */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | 36CA15881DEB2F3C000FE4CA /* MLNavigationBarTransition.app */, 125 | 36CA15A11DEB2F3C000FE4CA /* MLNavigationBarTransitionTests.xctest */, 126 | 36CA15AC1DEB2F3C000FE4CA /* MLNavigationBarTransitionUITests.xctest */, 127 | ); 128 | name = Products; 129 | sourceTree = ""; 130 | }; 131 | 36CA158A1DEB2F3C000FE4CA /* MLNavigationBarTransition */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 36408A941DEEBB78005A3BCF /* UINavigationController+StatusStyle.h */, 135 | 36408A951DEEBB78005A3BCF /* UINavigationController+StatusStyle.m */, 136 | 36408A8D1DEEB59E005A3BCF /* MLPickerButton */, 137 | 36408A911DEEB5AC005A3BCF /* BaseViewController.h */, 138 | 36408A921DEEB5AC005A3BCF /* BaseViewController.m */, 139 | 36CA15911DEB2F3C000FE4CA /* ViewController.h */, 140 | 36CA15921DEB2F3C000FE4CA /* ViewController.m */, 141 | 36CA158E1DEB2F3C000FE4CA /* AppDelegate.h */, 142 | 36CA158F1DEB2F3C000FE4CA /* AppDelegate.m */, 143 | 36CA15971DEB2F3C000FE4CA /* Assets.xcassets */, 144 | 36CA159C1DEB2F3C000FE4CA /* Info.plist */, 145 | 36CA158B1DEB2F3C000FE4CA /* Supporting Files */, 146 | ); 147 | path = MLNavigationBarTransition; 148 | sourceTree = ""; 149 | }; 150 | 36CA158B1DEB2F3C000FE4CA /* Supporting Files */ = { 151 | isa = PBXGroup; 152 | children = ( 153 | 36CA158C1DEB2F3C000FE4CA /* main.m */, 154 | ); 155 | name = "Supporting Files"; 156 | sourceTree = ""; 157 | }; 158 | 36CA15A41DEB2F3C000FE4CA /* MLNavigationBarTransitionTests */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | 36CA15A51DEB2F3C000FE4CA /* MLNavigationBarTransitionTests.m */, 162 | 36CA15A71DEB2F3C000FE4CA /* Info.plist */, 163 | ); 164 | path = MLNavigationBarTransitionTests; 165 | sourceTree = ""; 166 | }; 167 | 36CA15AF1DEB2F3C000FE4CA /* MLNavigationBarTransitionUITests */ = { 168 | isa = PBXGroup; 169 | children = ( 170 | 36CA15B01DEB2F3C000FE4CA /* MLNavigationBarTransitionUITests.m */, 171 | 36CA15B21DEB2F3C000FE4CA /* Info.plist */, 172 | ); 173 | path = MLNavigationBarTransitionUITests; 174 | sourceTree = ""; 175 | }; 176 | 4F7434085BC70DB6F860091B /* Frameworks */ = { 177 | isa = PBXGroup; 178 | children = ( 179 | A7AFE07447FD546BD96FD3B9 /* libPods-MLNavigationBarTransition.a */, 180 | ); 181 | name = Frameworks; 182 | sourceTree = ""; 183 | }; 184 | /* End PBXGroup section */ 185 | 186 | /* Begin PBXNativeTarget section */ 187 | 36CA15871DEB2F3C000FE4CA /* MLNavigationBarTransition */ = { 188 | isa = PBXNativeTarget; 189 | buildConfigurationList = 36CA15B51DEB2F3C000FE4CA /* Build configuration list for PBXNativeTarget "MLNavigationBarTransition" */; 190 | buildPhases = ( 191 | 6CC9425D578E069ECA0C9AF9 /* [CP] Check Pods Manifest.lock */, 192 | 36CA15841DEB2F3C000FE4CA /* Sources */, 193 | 36CA15851DEB2F3C000FE4CA /* Frameworks */, 194 | 36CA15861DEB2F3C000FE4CA /* Resources */, 195 | 41380E321ED00EC1CB70F031 /* [CP] Embed Pods Frameworks */, 196 | 8BBC68E92B3C370A937746EF /* [CP] Copy Pods Resources */, 197 | ); 198 | buildRules = ( 199 | ); 200 | dependencies = ( 201 | ); 202 | name = MLNavigationBarTransition; 203 | productName = MLNavigationBarTransition; 204 | productReference = 36CA15881DEB2F3C000FE4CA /* MLNavigationBarTransition.app */; 205 | productType = "com.apple.product-type.application"; 206 | }; 207 | 36CA15A01DEB2F3C000FE4CA /* MLNavigationBarTransitionTests */ = { 208 | isa = PBXNativeTarget; 209 | buildConfigurationList = 36CA15B81DEB2F3C000FE4CA /* Build configuration list for PBXNativeTarget "MLNavigationBarTransitionTests" */; 210 | buildPhases = ( 211 | 36CA159D1DEB2F3C000FE4CA /* Sources */, 212 | 36CA159E1DEB2F3C000FE4CA /* Frameworks */, 213 | 36CA159F1DEB2F3C000FE4CA /* Resources */, 214 | ); 215 | buildRules = ( 216 | ); 217 | dependencies = ( 218 | 36CA15A31DEB2F3C000FE4CA /* PBXTargetDependency */, 219 | ); 220 | name = MLNavigationBarTransitionTests; 221 | productName = MLNavigationBarTransitionTests; 222 | productReference = 36CA15A11DEB2F3C000FE4CA /* MLNavigationBarTransitionTests.xctest */; 223 | productType = "com.apple.product-type.bundle.unit-test"; 224 | }; 225 | 36CA15AB1DEB2F3C000FE4CA /* MLNavigationBarTransitionUITests */ = { 226 | isa = PBXNativeTarget; 227 | buildConfigurationList = 36CA15BB1DEB2F3C000FE4CA /* Build configuration list for PBXNativeTarget "MLNavigationBarTransitionUITests" */; 228 | buildPhases = ( 229 | 36CA15A81DEB2F3C000FE4CA /* Sources */, 230 | 36CA15A91DEB2F3C000FE4CA /* Frameworks */, 231 | 36CA15AA1DEB2F3C000FE4CA /* Resources */, 232 | ); 233 | buildRules = ( 234 | ); 235 | dependencies = ( 236 | 36CA15AE1DEB2F3C000FE4CA /* PBXTargetDependency */, 237 | ); 238 | name = MLNavigationBarTransitionUITests; 239 | productName = MLNavigationBarTransitionUITests; 240 | productReference = 36CA15AC1DEB2F3C000FE4CA /* MLNavigationBarTransitionUITests.xctest */; 241 | productType = "com.apple.product-type.bundle.ui-testing"; 242 | }; 243 | /* End PBXNativeTarget section */ 244 | 245 | /* Begin PBXProject section */ 246 | 36CA15801DEB2F3C000FE4CA /* Project object */ = { 247 | isa = PBXProject; 248 | attributes = { 249 | LastUpgradeCheck = 0900; 250 | ORGANIZATIONNAME = molon; 251 | TargetAttributes = { 252 | 36CA15871DEB2F3C000FE4CA = { 253 | CreatedOnToolsVersion = 7.3.1; 254 | DevelopmentTeam = PDL85JB6BQ; 255 | }; 256 | 36CA15A01DEB2F3C000FE4CA = { 257 | CreatedOnToolsVersion = 7.3.1; 258 | TestTargetID = 36CA15871DEB2F3C000FE4CA; 259 | }; 260 | 36CA15AB1DEB2F3C000FE4CA = { 261 | CreatedOnToolsVersion = 7.3.1; 262 | TestTargetID = 36CA15871DEB2F3C000FE4CA; 263 | }; 264 | }; 265 | }; 266 | buildConfigurationList = 36CA15831DEB2F3C000FE4CA /* Build configuration list for PBXProject "MLNavigationBarTransition" */; 267 | compatibilityVersion = "Xcode 3.2"; 268 | developmentRegion = English; 269 | hasScannedForEncodings = 0; 270 | knownRegions = ( 271 | en, 272 | Base, 273 | ); 274 | mainGroup = 36CA157F1DEB2F3C000FE4CA; 275 | productRefGroup = 36CA15891DEB2F3C000FE4CA /* Products */; 276 | projectDirPath = ""; 277 | projectRoot = ""; 278 | targets = ( 279 | 36CA15871DEB2F3C000FE4CA /* MLNavigationBarTransition */, 280 | 36CA15A01DEB2F3C000FE4CA /* MLNavigationBarTransitionTests */, 281 | 36CA15AB1DEB2F3C000FE4CA /* MLNavigationBarTransitionUITests */, 282 | ); 283 | }; 284 | /* End PBXProject section */ 285 | 286 | /* Begin PBXResourcesBuildPhase section */ 287 | 36CA15861DEB2F3C000FE4CA /* Resources */ = { 288 | isa = PBXResourcesBuildPhase; 289 | buildActionMask = 2147483647; 290 | files = ( 291 | 36CA15981DEB2F3C000FE4CA /* Assets.xcassets in Resources */, 292 | ); 293 | runOnlyForDeploymentPostprocessing = 0; 294 | }; 295 | 36CA159F1DEB2F3C000FE4CA /* Resources */ = { 296 | isa = PBXResourcesBuildPhase; 297 | buildActionMask = 2147483647; 298 | files = ( 299 | ); 300 | runOnlyForDeploymentPostprocessing = 0; 301 | }; 302 | 36CA15AA1DEB2F3C000FE4CA /* Resources */ = { 303 | isa = PBXResourcesBuildPhase; 304 | buildActionMask = 2147483647; 305 | files = ( 306 | ); 307 | runOnlyForDeploymentPostprocessing = 0; 308 | }; 309 | /* End PBXResourcesBuildPhase section */ 310 | 311 | /* Begin PBXShellScriptBuildPhase section */ 312 | 41380E321ED00EC1CB70F031 /* [CP] Embed Pods Frameworks */ = { 313 | isa = PBXShellScriptBuildPhase; 314 | buildActionMask = 2147483647; 315 | files = ( 316 | ); 317 | inputPaths = ( 318 | ); 319 | name = "[CP] Embed Pods Frameworks"; 320 | outputPaths = ( 321 | ); 322 | runOnlyForDeploymentPostprocessing = 0; 323 | shellPath = /bin/sh; 324 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-MLNavigationBarTransition/Pods-MLNavigationBarTransition-frameworks.sh\"\n"; 325 | showEnvVarsInLog = 0; 326 | }; 327 | 6CC9425D578E069ECA0C9AF9 /* [CP] Check Pods Manifest.lock */ = { 328 | isa = PBXShellScriptBuildPhase; 329 | buildActionMask = 2147483647; 330 | files = ( 331 | ); 332 | inputPaths = ( 333 | ); 334 | name = "[CP] Check Pods Manifest.lock"; 335 | outputPaths = ( 336 | ); 337 | runOnlyForDeploymentPostprocessing = 0; 338 | shellPath = /bin/sh; 339 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; 340 | showEnvVarsInLog = 0; 341 | }; 342 | 8BBC68E92B3C370A937746EF /* [CP] Copy Pods Resources */ = { 343 | isa = PBXShellScriptBuildPhase; 344 | buildActionMask = 2147483647; 345 | files = ( 346 | ); 347 | inputPaths = ( 348 | ); 349 | name = "[CP] Copy Pods Resources"; 350 | outputPaths = ( 351 | ); 352 | runOnlyForDeploymentPostprocessing = 0; 353 | shellPath = /bin/sh; 354 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-MLNavigationBarTransition/Pods-MLNavigationBarTransition-resources.sh\"\n"; 355 | showEnvVarsInLog = 0; 356 | }; 357 | /* End PBXShellScriptBuildPhase section */ 358 | 359 | /* Begin PBXSourcesBuildPhase section */ 360 | 36CA15841DEB2F3C000FE4CA /* Sources */ = { 361 | isa = PBXSourcesBuildPhase; 362 | buildActionMask = 2147483647; 363 | files = ( 364 | 36CA15931DEB2F3C000FE4CA /* ViewController.m in Sources */, 365 | 36408A961DEEBB78005A3BCF /* UINavigationController+StatusStyle.m in Sources */, 366 | 36408A931DEEB5AC005A3BCF /* BaseViewController.m in Sources */, 367 | 36CA15901DEB2F3C000FE4CA /* AppDelegate.m in Sources */, 368 | 36CA158D1DEB2F3C000FE4CA /* main.m in Sources */, 369 | 36408A901DEEB59E005A3BCF /* MLPickerButton.m in Sources */, 370 | ); 371 | runOnlyForDeploymentPostprocessing = 0; 372 | }; 373 | 36CA159D1DEB2F3C000FE4CA /* Sources */ = { 374 | isa = PBXSourcesBuildPhase; 375 | buildActionMask = 2147483647; 376 | files = ( 377 | 36CA15A61DEB2F3C000FE4CA /* MLNavigationBarTransitionTests.m in Sources */, 378 | ); 379 | runOnlyForDeploymentPostprocessing = 0; 380 | }; 381 | 36CA15A81DEB2F3C000FE4CA /* Sources */ = { 382 | isa = PBXSourcesBuildPhase; 383 | buildActionMask = 2147483647; 384 | files = ( 385 | 36CA15B11DEB2F3C000FE4CA /* MLNavigationBarTransitionUITests.m in Sources */, 386 | ); 387 | runOnlyForDeploymentPostprocessing = 0; 388 | }; 389 | /* End PBXSourcesBuildPhase section */ 390 | 391 | /* Begin PBXTargetDependency section */ 392 | 36CA15A31DEB2F3C000FE4CA /* PBXTargetDependency */ = { 393 | isa = PBXTargetDependency; 394 | target = 36CA15871DEB2F3C000FE4CA /* MLNavigationBarTransition */; 395 | targetProxy = 36CA15A21DEB2F3C000FE4CA /* PBXContainerItemProxy */; 396 | }; 397 | 36CA15AE1DEB2F3C000FE4CA /* PBXTargetDependency */ = { 398 | isa = PBXTargetDependency; 399 | target = 36CA15871DEB2F3C000FE4CA /* MLNavigationBarTransition */; 400 | targetProxy = 36CA15AD1DEB2F3C000FE4CA /* PBXContainerItemProxy */; 401 | }; 402 | /* End PBXTargetDependency section */ 403 | 404 | /* Begin XCBuildConfiguration section */ 405 | 36CA15B31DEB2F3C000FE4CA /* Debug */ = { 406 | isa = XCBuildConfiguration; 407 | buildSettings = { 408 | ALWAYS_SEARCH_USER_PATHS = NO; 409 | CLANG_ANALYZER_NONNULL = YES; 410 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 411 | CLANG_CXX_LIBRARY = "libc++"; 412 | CLANG_ENABLE_MODULES = YES; 413 | CLANG_ENABLE_OBJC_ARC = YES; 414 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 415 | CLANG_WARN_BOOL_CONVERSION = YES; 416 | CLANG_WARN_COMMA = YES; 417 | CLANG_WARN_CONSTANT_CONVERSION = YES; 418 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 419 | CLANG_WARN_EMPTY_BODY = YES; 420 | CLANG_WARN_ENUM_CONVERSION = YES; 421 | CLANG_WARN_INFINITE_RECURSION = YES; 422 | CLANG_WARN_INT_CONVERSION = YES; 423 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 424 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 425 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 426 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 427 | CLANG_WARN_STRICT_PROTOTYPES = YES; 428 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 429 | CLANG_WARN_UNREACHABLE_CODE = YES; 430 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 431 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 432 | COPY_PHASE_STRIP = NO; 433 | DEBUG_INFORMATION_FORMAT = dwarf; 434 | ENABLE_STRICT_OBJC_MSGSEND = YES; 435 | ENABLE_TESTABILITY = YES; 436 | GCC_C_LANGUAGE_STANDARD = gnu99; 437 | GCC_DYNAMIC_NO_PIC = NO; 438 | GCC_NO_COMMON_BLOCKS = YES; 439 | GCC_OPTIMIZATION_LEVEL = 0; 440 | GCC_PREPROCESSOR_DEFINITIONS = ( 441 | "DEBUG=1", 442 | "$(inherited)", 443 | ); 444 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 445 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 446 | GCC_WARN_UNDECLARED_SELECTOR = YES; 447 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 448 | GCC_WARN_UNUSED_FUNCTION = YES; 449 | GCC_WARN_UNUSED_VARIABLE = YES; 450 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 451 | MTL_ENABLE_DEBUG_INFO = YES; 452 | ONLY_ACTIVE_ARCH = YES; 453 | SDKROOT = iphoneos; 454 | TARGETED_DEVICE_FAMILY = "1,2"; 455 | }; 456 | name = Debug; 457 | }; 458 | 36CA15B41DEB2F3C000FE4CA /* Release */ = { 459 | isa = XCBuildConfiguration; 460 | buildSettings = { 461 | ALWAYS_SEARCH_USER_PATHS = NO; 462 | CLANG_ANALYZER_NONNULL = YES; 463 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 464 | CLANG_CXX_LIBRARY = "libc++"; 465 | CLANG_ENABLE_MODULES = YES; 466 | CLANG_ENABLE_OBJC_ARC = YES; 467 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 468 | CLANG_WARN_BOOL_CONVERSION = YES; 469 | CLANG_WARN_COMMA = YES; 470 | CLANG_WARN_CONSTANT_CONVERSION = YES; 471 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 472 | CLANG_WARN_EMPTY_BODY = YES; 473 | CLANG_WARN_ENUM_CONVERSION = YES; 474 | CLANG_WARN_INFINITE_RECURSION = YES; 475 | CLANG_WARN_INT_CONVERSION = YES; 476 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 477 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 478 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 479 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 480 | CLANG_WARN_STRICT_PROTOTYPES = YES; 481 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 482 | CLANG_WARN_UNREACHABLE_CODE = YES; 483 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 484 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 485 | COPY_PHASE_STRIP = NO; 486 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 487 | ENABLE_NS_ASSERTIONS = NO; 488 | ENABLE_STRICT_OBJC_MSGSEND = YES; 489 | GCC_C_LANGUAGE_STANDARD = gnu99; 490 | GCC_NO_COMMON_BLOCKS = YES; 491 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 492 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 493 | GCC_WARN_UNDECLARED_SELECTOR = YES; 494 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 495 | GCC_WARN_UNUSED_FUNCTION = YES; 496 | GCC_WARN_UNUSED_VARIABLE = YES; 497 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 498 | MTL_ENABLE_DEBUG_INFO = NO; 499 | SDKROOT = iphoneos; 500 | TARGETED_DEVICE_FAMILY = "1,2"; 501 | VALIDATE_PRODUCT = YES; 502 | }; 503 | name = Release; 504 | }; 505 | 36CA15B61DEB2F3C000FE4CA /* Debug */ = { 506 | isa = XCBuildConfiguration; 507 | baseConfigurationReference = 65F9AA77249756739A9195CA /* Pods-MLNavigationBarTransition.debug.xcconfig */; 508 | buildSettings = { 509 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 510 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 511 | DEVELOPMENT_TEAM = PDL85JB6BQ; 512 | INFOPLIST_FILE = MLNavigationBarTransition/Info.plist; 513 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 514 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 515 | PRODUCT_BUNDLE_IDENTIFIER = com.molon.MLNavigationBarTransition; 516 | PRODUCT_NAME = "$(TARGET_NAME)"; 517 | TARGETED_DEVICE_FAMILY = 1; 518 | }; 519 | name = Debug; 520 | }; 521 | 36CA15B71DEB2F3C000FE4CA /* Release */ = { 522 | isa = XCBuildConfiguration; 523 | baseConfigurationReference = AAC1587612449FC10C91F9DC /* Pods-MLNavigationBarTransition.release.xcconfig */; 524 | buildSettings = { 525 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 526 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 527 | DEVELOPMENT_TEAM = PDL85JB6BQ; 528 | INFOPLIST_FILE = MLNavigationBarTransition/Info.plist; 529 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 530 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 531 | PRODUCT_BUNDLE_IDENTIFIER = com.molon.MLNavigationBarTransition; 532 | PRODUCT_NAME = "$(TARGET_NAME)"; 533 | TARGETED_DEVICE_FAMILY = 1; 534 | }; 535 | name = Release; 536 | }; 537 | 36CA15B91DEB2F3C000FE4CA /* Debug */ = { 538 | isa = XCBuildConfiguration; 539 | buildSettings = { 540 | BUNDLE_LOADER = "$(TEST_HOST)"; 541 | INFOPLIST_FILE = MLNavigationBarTransitionTests/Info.plist; 542 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 543 | PRODUCT_BUNDLE_IDENTIFIER = com.molon.MLNavigationBarTransitionTests; 544 | PRODUCT_NAME = "$(TARGET_NAME)"; 545 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MLNavigationBarTransition.app/MLNavigationBarTransition"; 546 | }; 547 | name = Debug; 548 | }; 549 | 36CA15BA1DEB2F3C000FE4CA /* Release */ = { 550 | isa = XCBuildConfiguration; 551 | buildSettings = { 552 | BUNDLE_LOADER = "$(TEST_HOST)"; 553 | INFOPLIST_FILE = MLNavigationBarTransitionTests/Info.plist; 554 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 555 | PRODUCT_BUNDLE_IDENTIFIER = com.molon.MLNavigationBarTransitionTests; 556 | PRODUCT_NAME = "$(TARGET_NAME)"; 557 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MLNavigationBarTransition.app/MLNavigationBarTransition"; 558 | }; 559 | name = Release; 560 | }; 561 | 36CA15BC1DEB2F3C000FE4CA /* Debug */ = { 562 | isa = XCBuildConfiguration; 563 | buildSettings = { 564 | INFOPLIST_FILE = MLNavigationBarTransitionUITests/Info.plist; 565 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 566 | PRODUCT_BUNDLE_IDENTIFIER = com.molon.MLNavigationBarTransitionUITests; 567 | PRODUCT_NAME = "$(TARGET_NAME)"; 568 | TEST_TARGET_NAME = MLNavigationBarTransition; 569 | }; 570 | name = Debug; 571 | }; 572 | 36CA15BD1DEB2F3C000FE4CA /* Release */ = { 573 | isa = XCBuildConfiguration; 574 | buildSettings = { 575 | INFOPLIST_FILE = MLNavigationBarTransitionUITests/Info.plist; 576 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 577 | PRODUCT_BUNDLE_IDENTIFIER = com.molon.MLNavigationBarTransitionUITests; 578 | PRODUCT_NAME = "$(TARGET_NAME)"; 579 | TEST_TARGET_NAME = MLNavigationBarTransition; 580 | }; 581 | name = Release; 582 | }; 583 | /* End XCBuildConfiguration section */ 584 | 585 | /* Begin XCConfigurationList section */ 586 | 36CA15831DEB2F3C000FE4CA /* Build configuration list for PBXProject "MLNavigationBarTransition" */ = { 587 | isa = XCConfigurationList; 588 | buildConfigurations = ( 589 | 36CA15B31DEB2F3C000FE4CA /* Debug */, 590 | 36CA15B41DEB2F3C000FE4CA /* Release */, 591 | ); 592 | defaultConfigurationIsVisible = 0; 593 | defaultConfigurationName = Release; 594 | }; 595 | 36CA15B51DEB2F3C000FE4CA /* Build configuration list for PBXNativeTarget "MLNavigationBarTransition" */ = { 596 | isa = XCConfigurationList; 597 | buildConfigurations = ( 598 | 36CA15B61DEB2F3C000FE4CA /* Debug */, 599 | 36CA15B71DEB2F3C000FE4CA /* Release */, 600 | ); 601 | defaultConfigurationIsVisible = 0; 602 | defaultConfigurationName = Release; 603 | }; 604 | 36CA15B81DEB2F3C000FE4CA /* Build configuration list for PBXNativeTarget "MLNavigationBarTransitionTests" */ = { 605 | isa = XCConfigurationList; 606 | buildConfigurations = ( 607 | 36CA15B91DEB2F3C000FE4CA /* Debug */, 608 | 36CA15BA1DEB2F3C000FE4CA /* Release */, 609 | ); 610 | defaultConfigurationIsVisible = 0; 611 | defaultConfigurationName = Release; 612 | }; 613 | 36CA15BB1DEB2F3C000FE4CA /* Build configuration list for PBXNativeTarget "MLNavigationBarTransitionUITests" */ = { 614 | isa = XCConfigurationList; 615 | buildConfigurations = ( 616 | 36CA15BC1DEB2F3C000FE4CA /* Debug */, 617 | 36CA15BD1DEB2F3C000FE4CA /* Release */, 618 | ); 619 | defaultConfigurationIsVisible = 0; 620 | defaultConfigurationName = Release; 621 | }; 622 | /* End XCConfigurationList section */ 623 | }; 624 | rootObject = 36CA15801DEB2F3C000FE4CA /* Project object */; 625 | } 626 | --------------------------------------------------------------------------------