├── 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 | 
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 |
--------------------------------------------------------------------------------