├── .github └── workflows │ └── objective-c-xcode.yml ├── .gitignore ├── .swift-version ├── .travis.yml ├── CHANGELOG.md ├── Example ├── Podfile ├── Podfile.lock ├── RTRootNavigationController.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── RTRootNavigationController-Example.xcscheme ├── RTRootNavigationController.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── RTRootNavigationController │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── LaunchImage.launchimage │ │ │ └── Contents.json │ │ ├── about.imageset │ │ │ ├── Contents.json │ │ │ └── about.pdf │ │ ├── add_user_male.imageset │ │ │ ├── Contents.json │ │ │ └── add_user_male.pdf │ │ ├── apple.imageset │ │ │ ├── Contents.json │ │ │ └── apple@2x.png │ │ └── back.imageset │ │ │ ├── Contents.json │ │ │ └── back.pdf │ ├── Launch.storyboard │ ├── Main.storyboard │ ├── RTAppDelegate.h │ ├── RTAppDelegate.m │ ├── RTCollectionViewController.h │ ├── RTCollectionViewController.m │ ├── RTCustomNavigationBar.h │ ├── RTCustomNavigationBar.m │ ├── RTHideNavigationBarViewController.h │ ├── RTHideNavigationBarViewController.m │ ├── RTItemDetailViewController.h │ ├── RTItemDetailViewController.m │ ├── RTItemListViewController.h │ ├── RTItemListViewController.m │ ├── RTPushRemoveViewController.h │ ├── RTPushRemoveViewController.m │ ├── RTRootNavigationController-Info.plist │ ├── RTRootNavigationController-Prefix.pch │ ├── RTStaticTableViewController.h │ ├── RTStaticTableViewController.m │ ├── RTStatusHiddenViewController.h │ ├── RTStatusHiddenViewController.m │ ├── RTTableViewController.h │ ├── RTTableViewController.m │ ├── RTViewController.h │ ├── RTViewController.m │ ├── RTWebViewController.h │ ├── RTWebViewController.m │ ├── en.lproj │ │ └── InfoPlist.strings │ └── main.m └── Tests │ ├── Tests-Info.plist │ ├── Tests-Prefix.pch │ ├── Tests.m │ └── en.lproj │ └── InfoPlist.strings ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── README.md ├── RTRootNavigationController.podspec ├── RTRootNavigationController ├── Assets │ └── .gitkeep └── Classes │ ├── .gitkeep │ ├── RTRootNavigationController.h │ ├── RTRootNavigationController.m │ ├── RTViewControllerAnimatedTransitioning.h │ ├── UIViewController+RTRootNavigationController.h │ └── UIViewController+RTRootNavigationController.m ├── ScreenShot ├── 1.png └── 2.gif └── _Pods.xcodeproj /.github/workflows/objective-c-xcode.yml: -------------------------------------------------------------------------------- 1 | name: Xcode - Build and Analyze 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | jobs: 10 | build: 11 | name: Build and analyse default scheme using xcodebuild command 12 | runs-on: macos-latest 13 | 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v4 17 | with: 18 | fetch-tags: true 19 | - name: Lint 20 | env: 21 | scheme: ${{ 'default' }} 22 | run: | 23 | bundle install 24 | bundle exec pod lib lint 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata/ 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | 25 | Carthage 26 | # We recommend against adding the Pods directory to your .gitignore. However 27 | # you should judge for yourself, the pros and cons are mentioned at: 28 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 29 | # 30 | # Note: if you ignore the Pods directory, make sure to uncomment 31 | # `pod install` in .travis.yml 32 | # 33 | Pods/ 34 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 2.3 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # references: 2 | # * http://www.objc.io/issue-6/travis-ci.html 3 | # * https://github.com/supermarin/xcpretty#usage 4 | 5 | osx_image: xcode8.2 6 | language: objective-c 7 | cache: cocoapods 8 | xcode_project: Example/RTRootNavigationController.xcworkspace 9 | xcode_scheme: RTRootNavigationController-Example 10 | podfile: Example/Podfile 11 | before_install: 12 | - cd Example 13 | - pod update 14 | script: 15 | - cd ../ 16 | - pod lib lint 17 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 0.7.0 2 | 3 | - fix iOS 12 navigationBar subview is empty in `-viewDidLoad`, #222 #224; drop support for #11, if you are using **RDVTabBarController**, DO NOT update. 4 | 5 | 0.6.7 6 | 7 | - iOS 11 `preferredScreenEdgesDeferringSystemGestures` support 8 | 9 | 0.6.6 10 | 11 | - fix `UINavigationControllerDelegate` behavior, always pass user **VC** 12 | 13 | 0.6.5 14 | 15 | - use `navigationItem.title` first, then `title` 16 | 17 | 0.6.4 18 | 19 | - fix #147, `prefersHomeIndicatorAutoHidden` support 20 | 21 | 0.6.3 22 | 23 | - fix #92, now you can use `self.navigationController.viewControllers` to access siblings 24 | 25 | 0.6.2 26 | 27 | - fix #96 28 | 29 | 0.6.1 30 | 31 | - fix `-preferredStatusBarStyle` 32 | 33 | 0.6.0 34 | 35 | - *Notice*: default behavior change. If **VC** has set left item in `-viewDidLoad`, then interactive pop will be disabled by default, you can still set `rt_disableInteractivePop` to **NO** if you really want it. 36 | 37 | 0.5.26 38 | 39 | - interactive push support 40 | 41 | ```ruby 42 | pod 'RTRootNavigationController', :subspecs = ['Push'] 43 | ``` 44 | 45 | 0.5.25 46 | 47 | - deprecate `customBackItemWithTarget:action:`, use `rt_customBackItemWithTarget:action:` instead 48 | 49 | 0.5.24 50 | 51 | - add `popViewControllerAnimated:complete:` method 52 | 53 | 0.5.23 54 | 55 | - add a **NOTICE** for the view controller hierarchy change 56 | - fix #39 57 | 58 | 0.5.22 59 | 60 | - fix delegate method calling 61 | 62 | 0.5.21 63 | 64 | - fix #27 65 | 66 | 0.5.20 67 | 68 | - fix #16 69 | 70 | 0.5.19 71 | 72 | - fix #14 73 | 74 | 0.5.18 75 | 76 | - fix #12 77 | 78 | 0.5.17 79 | 80 | - fix #11 81 | 82 | 0.5.16 83 | 84 | - potential bug 85 | 86 | 0.5.15 87 | 88 | - fix #7 89 | 90 | 0.5.14 91 | 92 | - fix #4 93 | 94 | 0.5.13 95 | 96 | - add `removeViewController:animated:` method 97 | - fix pop to root completion block calling 98 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | 2 | platform :ios, '11.0' 3 | use_frameworks! 4 | 5 | target 'RTRootNavigationController_Example' do 6 | pod 'RTRootNavigationController', :path => '../', :subspecs => ['Push'] 7 | 8 | target 'RTRootNavigationController_Tests' do 9 | 10 | end 11 | end 12 | 13 | post_install do |installer| 14 | installer.pods_project.targets.each do |target| 15 | target.build_configurations.each do |config| 16 | # config.build_settings['ENABLE_BITCODE'] = 'NO' 17 | config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0' 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - RTInteractivePush (0.1.6) 3 | - RTRootNavigationController/Core (0.8.1) 4 | - RTRootNavigationController/Push (0.8.1): 5 | - RTInteractivePush (~> 0.1.6) 6 | - RTRootNavigationController/Core 7 | 8 | DEPENDENCIES: 9 | - RTRootNavigationController/Push (from `../`) 10 | 11 | SPEC REPOS: 12 | trunk: 13 | - RTInteractivePush 14 | 15 | EXTERNAL SOURCES: 16 | RTRootNavigationController: 17 | :path: "../" 18 | 19 | SPEC CHECKSUMS: 20 | RTInteractivePush: b77e14751d7856da6c86248820defa3aa2d68b03 21 | RTRootNavigationController: ca443783baf6ff65a70c4d21ce0eedbbc1fec1fe 22 | 23 | PODFILE CHECKSUM: 9e402247368443c125c5320076cfb21c49e9a7da 24 | 25 | COCOAPODS: 1.14.2 26 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; }; 11 | 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58F195388D20070C39A /* CoreGraphics.framework */; }; 12 | 6003F592195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; }; 13 | 6003F598195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F596195388D20070C39A /* InfoPlist.strings */; }; 14 | 6003F59A195388D20070C39A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F599195388D20070C39A /* main.m */; }; 15 | 6003F59E195388D20070C39A /* RTAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F59D195388D20070C39A /* RTAppDelegate.m */; }; 16 | 6003F5A7195388D20070C39A /* RTViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5A6195388D20070C39A /* RTViewController.m */; }; 17 | 6003F5A9195388D20070C39A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5A8195388D20070C39A /* Images.xcassets */; }; 18 | 6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F5AF195388D20070C39A /* XCTest.framework */; }; 19 | 6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; }; 20 | 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; }; 21 | 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5B8195388D20070C39A /* InfoPlist.strings */; }; 22 | 6003F5BC195388D20070C39A /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5BB195388D20070C39A /* Tests.m */; }; 23 | 7754DE23C98A4856C653731B /* Pods_RTRootNavigationController_Example_RTRootNavigationController_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 041DF0A8B0027264C4093D15 /* Pods_RTRootNavigationController_Example_RTRootNavigationController_Tests.framework */; }; 24 | 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */; }; 25 | 93A95D8D8AF7C67635D9CF27 /* Pods_RTRootNavigationController_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AC461907B53EF1711816DC02 /* Pods_RTRootNavigationController_Example.framework */; }; 26 | 9C16AF1F1D09518100873B86 /* Launch.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9C16AF1E1D09518100873B86 /* Launch.storyboard */; }; 27 | 9C16AF221D09551E00873B86 /* RTPushRemoveViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C16AF211D09551E00873B86 /* RTPushRemoveViewController.m */; }; 28 | 9C16AF251D0957D400873B86 /* RTTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C16AF241D0957D400873B86 /* RTTableViewController.m */; }; 29 | 9C16AF281D095EC700873B86 /* RTStaticTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C16AF271D095EC700873B86 /* RTStaticTableViewController.m */; }; 30 | 9C16AF2C1D097CEB00873B86 /* RTCustomNavigationBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C16AF2B1D097CEB00873B86 /* RTCustomNavigationBar.m */; }; 31 | 9C2994E91D09B83C007722C1 /* RTItemListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C2994E81D09B83C007722C1 /* RTItemListViewController.m */; }; 32 | 9C2994EC1D09B84B007722C1 /* RTItemDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C2994EB1D09B84B007722C1 /* RTItemDetailViewController.m */; }; 33 | 9C2994EF1D0A4D6F007722C1 /* RTWebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C2994EE1D0A4D6F007722C1 /* RTWebViewController.m */; }; 34 | 9C323D281F0E571100A18836 /* CHANGELOG.md in Sources */ = {isa = PBXBuildFile; fileRef = 9C323D271F0E571100A18836 /* CHANGELOG.md */; }; 35 | 9C7832C11D09111F00693F14 /* RTHideNavigationBarViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C7832C01D09111F00693F14 /* RTHideNavigationBarViewController.m */; }; 36 | 9C7832C41D09152900693F14 /* RTCollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C7832C31D09152900693F14 /* RTCollectionViewController.m */; }; 37 | 9C9863FD1F32BDE400CF307B /* RTStatusHiddenViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C9863FC1F32BDE400CF307B /* RTStatusHiddenViewController.m */; }; 38 | /* End PBXBuildFile section */ 39 | 40 | /* Begin PBXContainerItemProxy section */ 41 | 6003F5B3195388D20070C39A /* PBXContainerItemProxy */ = { 42 | isa = PBXContainerItemProxy; 43 | containerPortal = 6003F582195388D10070C39A /* Project object */; 44 | proxyType = 1; 45 | remoteGlobalIDString = 6003F589195388D20070C39A; 46 | remoteInfo = RTRootNavigationController; 47 | }; 48 | /* End PBXContainerItemProxy section */ 49 | 50 | /* Begin PBXFileReference section */ 51 | 041DF0A8B0027264C4093D15 /* Pods_RTRootNavigationController_Example_RTRootNavigationController_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RTRootNavigationController_Example_RTRootNavigationController_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 4B6ECD73E96DEED1827971A4 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 53 | 4C78C63219178A258FA60E34 /* Pods-RTRootNavigationController_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RTRootNavigationController_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RTRootNavigationController_Example/Pods-RTRootNavigationController_Example.debug.xcconfig"; sourceTree = ""; }; 54 | 6003F58A195388D20070C39A /* RTRootNavigationController_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RTRootNavigationController_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 55 | 6003F58D195388D20070C39A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 56 | 6003F58F195388D20070C39A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 57 | 6003F591195388D20070C39A /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 58 | 6003F595195388D20070C39A /* RTRootNavigationController-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RTRootNavigationController-Info.plist"; sourceTree = ""; }; 59 | 6003F597195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 60 | 6003F599195388D20070C39A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 61 | 6003F59B195388D20070C39A /* RTRootNavigationController-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RTRootNavigationController-Prefix.pch"; sourceTree = ""; }; 62 | 6003F59C195388D20070C39A /* RTAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RTAppDelegate.h; sourceTree = ""; }; 63 | 6003F59D195388D20070C39A /* RTAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RTAppDelegate.m; sourceTree = ""; }; 64 | 6003F5A5195388D20070C39A /* RTViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RTViewController.h; sourceTree = ""; }; 65 | 6003F5A6195388D20070C39A /* RTViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RTViewController.m; sourceTree = ""; }; 66 | 6003F5A8195388D20070C39A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 67 | 6003F5AE195388D20070C39A /* RTRootNavigationController_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RTRootNavigationController_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 68 | 6003F5AF195388D20070C39A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 69 | 6003F5B7195388D20070C39A /* Tests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Tests-Info.plist"; sourceTree = ""; }; 70 | 6003F5B9195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 71 | 6003F5BB195388D20070C39A /* Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Tests.m; sourceTree = ""; }; 72 | 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Tests-Prefix.pch"; sourceTree = ""; }; 73 | 67C2BF2B52D3057E8417FB63 /* RTRootNavigationController.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = RTRootNavigationController.podspec; path = ../RTRootNavigationController.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 74 | 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; 75 | 9C16AF1E1D09518100873B86 /* Launch.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Launch.storyboard; sourceTree = ""; }; 76 | 9C16AF201D09551E00873B86 /* RTPushRemoveViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTPushRemoveViewController.h; sourceTree = ""; }; 77 | 9C16AF211D09551E00873B86 /* RTPushRemoveViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RTPushRemoveViewController.m; sourceTree = ""; }; 78 | 9C16AF231D0957D400873B86 /* RTTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTTableViewController.h; sourceTree = ""; }; 79 | 9C16AF241D0957D400873B86 /* RTTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RTTableViewController.m; sourceTree = ""; }; 80 | 9C16AF261D095EC700873B86 /* RTStaticTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTStaticTableViewController.h; sourceTree = ""; }; 81 | 9C16AF271D095EC700873B86 /* RTStaticTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RTStaticTableViewController.m; sourceTree = ""; }; 82 | 9C16AF2A1D097CEB00873B86 /* RTCustomNavigationBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCustomNavigationBar.h; sourceTree = ""; }; 83 | 9C16AF2B1D097CEB00873B86 /* RTCustomNavigationBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RTCustomNavigationBar.m; sourceTree = ""; }; 84 | 9C2994E71D09B83C007722C1 /* RTItemListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTItemListViewController.h; sourceTree = ""; }; 85 | 9C2994E81D09B83C007722C1 /* RTItemListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RTItemListViewController.m; sourceTree = ""; }; 86 | 9C2994EA1D09B84B007722C1 /* RTItemDetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTItemDetailViewController.h; sourceTree = ""; }; 87 | 9C2994EB1D09B84B007722C1 /* RTItemDetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RTItemDetailViewController.m; sourceTree = ""; }; 88 | 9C2994ED1D0A4D6F007722C1 /* RTWebViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTWebViewController.h; sourceTree = ""; }; 89 | 9C2994EE1D0A4D6F007722C1 /* RTWebViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RTWebViewController.m; sourceTree = ""; }; 90 | 9C323D271F0E571100A18836 /* CHANGELOG.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; name = CHANGELOG.md; path = ../CHANGELOG.md; sourceTree = ""; }; 91 | 9C7832BF1D09111F00693F14 /* RTHideNavigationBarViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTHideNavigationBarViewController.h; sourceTree = ""; }; 92 | 9C7832C01D09111F00693F14 /* RTHideNavigationBarViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RTHideNavigationBarViewController.m; sourceTree = ""; }; 93 | 9C7832C21D09152900693F14 /* RTCollectionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTCollectionViewController.h; sourceTree = ""; }; 94 | 9C7832C31D09152900693F14 /* RTCollectionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RTCollectionViewController.m; sourceTree = ""; }; 95 | 9C9863FB1F32BDE400CF307B /* RTStatusHiddenViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTStatusHiddenViewController.h; sourceTree = ""; }; 96 | 9C9863FC1F32BDE400CF307B /* RTStatusHiddenViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RTStatusHiddenViewController.m; sourceTree = ""; }; 97 | A5267346A018343C32093DA1 /* Pods-RTRootNavigationController_Example-RTRootNavigationController_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RTRootNavigationController_Example-RTRootNavigationController_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RTRootNavigationController_Example-RTRootNavigationController_Tests/Pods-RTRootNavigationController_Example-RTRootNavigationController_Tests.release.xcconfig"; sourceTree = ""; }; 98 | AC461907B53EF1711816DC02 /* Pods_RTRootNavigationController_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RTRootNavigationController_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 99 | B930DAFF5ACFE0FF66B80F25 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; 100 | C6B0AF5F8FE50A6D2E11BBBC /* Pods-RTRootNavigationController_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RTRootNavigationController_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-RTRootNavigationController_Example/Pods-RTRootNavigationController_Example.release.xcconfig"; sourceTree = ""; }; 101 | F53B590EB877567165CF7290 /* Pods-RTRootNavigationController_Example-RTRootNavigationController_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RTRootNavigationController_Example-RTRootNavigationController_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RTRootNavigationController_Example-RTRootNavigationController_Tests/Pods-RTRootNavigationController_Example-RTRootNavigationController_Tests.debug.xcconfig"; sourceTree = ""; }; 102 | /* End PBXFileReference section */ 103 | 104 | /* Begin PBXFrameworksBuildPhase section */ 105 | 6003F587195388D20070C39A /* Frameworks */ = { 106 | isa = PBXFrameworksBuildPhase; 107 | buildActionMask = 2147483647; 108 | files = ( 109 | 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */, 110 | 6003F592195388D20070C39A /* UIKit.framework in Frameworks */, 111 | 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */, 112 | 93A95D8D8AF7C67635D9CF27 /* Pods_RTRootNavigationController_Example.framework in Frameworks */, 113 | ); 114 | runOnlyForDeploymentPostprocessing = 0; 115 | }; 116 | 6003F5AB195388D20070C39A /* Frameworks */ = { 117 | isa = PBXFrameworksBuildPhase; 118 | buildActionMask = 2147483647; 119 | files = ( 120 | 6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */, 121 | 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */, 122 | 6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */, 123 | 7754DE23C98A4856C653731B /* Pods_RTRootNavigationController_Example_RTRootNavigationController_Tests.framework in Frameworks */, 124 | ); 125 | runOnlyForDeploymentPostprocessing = 0; 126 | }; 127 | /* End PBXFrameworksBuildPhase section */ 128 | 129 | /* Begin PBXGroup section */ 130 | 6003F581195388D10070C39A = { 131 | isa = PBXGroup; 132 | children = ( 133 | 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */, 134 | 6003F593195388D20070C39A /* Example for RTRootNavigationController */, 135 | 6003F5B5195388D20070C39A /* Tests */, 136 | 6003F58C195388D20070C39A /* Frameworks */, 137 | 6003F58B195388D20070C39A /* Products */, 138 | F96BE6D2D993D004DBE65F76 /* Pods */, 139 | ); 140 | sourceTree = ""; 141 | }; 142 | 6003F58B195388D20070C39A /* Products */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | 6003F58A195388D20070C39A /* RTRootNavigationController_Example.app */, 146 | 6003F5AE195388D20070C39A /* RTRootNavigationController_Tests.xctest */, 147 | ); 148 | name = Products; 149 | sourceTree = ""; 150 | }; 151 | 6003F58C195388D20070C39A /* Frameworks */ = { 152 | isa = PBXGroup; 153 | children = ( 154 | 6003F58D195388D20070C39A /* Foundation.framework */, 155 | 6003F58F195388D20070C39A /* CoreGraphics.framework */, 156 | 6003F591195388D20070C39A /* UIKit.framework */, 157 | 6003F5AF195388D20070C39A /* XCTest.framework */, 158 | AC461907B53EF1711816DC02 /* Pods_RTRootNavigationController_Example.framework */, 159 | 041DF0A8B0027264C4093D15 /* Pods_RTRootNavigationController_Example_RTRootNavigationController_Tests.framework */, 160 | ); 161 | name = Frameworks; 162 | sourceTree = ""; 163 | }; 164 | 6003F593195388D20070C39A /* Example for RTRootNavigationController */ = { 165 | isa = PBXGroup; 166 | children = ( 167 | 6003F5A8195388D20070C39A /* Images.xcassets */, 168 | 9C16AF1E1D09518100873B86 /* Launch.storyboard */, 169 | 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */, 170 | 6003F59C195388D20070C39A /* RTAppDelegate.h */, 171 | 6003F59D195388D20070C39A /* RTAppDelegate.m */, 172 | 6003F594195388D20070C39A /* Supporting Files */, 173 | 9C16AF291D097CD100873B86 /* ViewControllers */, 174 | 9C16AF2D1D097D4200873B86 /* Views */, 175 | ); 176 | name = "Example for RTRootNavigationController"; 177 | path = RTRootNavigationController; 178 | sourceTree = ""; 179 | }; 180 | 6003F594195388D20070C39A /* Supporting Files */ = { 181 | isa = PBXGroup; 182 | children = ( 183 | 6003F595195388D20070C39A /* RTRootNavigationController-Info.plist */, 184 | 6003F596195388D20070C39A /* InfoPlist.strings */, 185 | 6003F599195388D20070C39A /* main.m */, 186 | 6003F59B195388D20070C39A /* RTRootNavigationController-Prefix.pch */, 187 | ); 188 | name = "Supporting Files"; 189 | sourceTree = ""; 190 | }; 191 | 6003F5B5195388D20070C39A /* Tests */ = { 192 | isa = PBXGroup; 193 | children = ( 194 | 6003F5BB195388D20070C39A /* Tests.m */, 195 | 6003F5B6195388D20070C39A /* Supporting Files */, 196 | ); 197 | path = Tests; 198 | sourceTree = ""; 199 | }; 200 | 6003F5B6195388D20070C39A /* Supporting Files */ = { 201 | isa = PBXGroup; 202 | children = ( 203 | 6003F5B7195388D20070C39A /* Tests-Info.plist */, 204 | 6003F5B8195388D20070C39A /* InfoPlist.strings */, 205 | 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */, 206 | ); 207 | name = "Supporting Files"; 208 | sourceTree = ""; 209 | }; 210 | 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */ = { 211 | isa = PBXGroup; 212 | children = ( 213 | 9C323D271F0E571100A18836 /* CHANGELOG.md */, 214 | B930DAFF5ACFE0FF66B80F25 /* LICENSE */, 215 | 4B6ECD73E96DEED1827971A4 /* README.md */, 216 | 67C2BF2B52D3057E8417FB63 /* RTRootNavigationController.podspec */, 217 | ); 218 | name = "Podspec Metadata"; 219 | sourceTree = ""; 220 | }; 221 | 9C16AF291D097CD100873B86 /* ViewControllers */ = { 222 | isa = PBXGroup; 223 | children = ( 224 | 9C7832C21D09152900693F14 /* RTCollectionViewController.h */, 225 | 9C7832C31D09152900693F14 /* RTCollectionViewController.m */, 226 | 9C7832BF1D09111F00693F14 /* RTHideNavigationBarViewController.h */, 227 | 9C7832C01D09111F00693F14 /* RTHideNavigationBarViewController.m */, 228 | 9C2994EA1D09B84B007722C1 /* RTItemDetailViewController.h */, 229 | 9C2994EB1D09B84B007722C1 /* RTItemDetailViewController.m */, 230 | 9C2994E71D09B83C007722C1 /* RTItemListViewController.h */, 231 | 9C2994E81D09B83C007722C1 /* RTItemListViewController.m */, 232 | 9C16AF201D09551E00873B86 /* RTPushRemoveViewController.h */, 233 | 9C16AF211D09551E00873B86 /* RTPushRemoveViewController.m */, 234 | 9C16AF261D095EC700873B86 /* RTStaticTableViewController.h */, 235 | 9C16AF271D095EC700873B86 /* RTStaticTableViewController.m */, 236 | 9C16AF231D0957D400873B86 /* RTTableViewController.h */, 237 | 9C16AF241D0957D400873B86 /* RTTableViewController.m */, 238 | 6003F5A5195388D20070C39A /* RTViewController.h */, 239 | 6003F5A6195388D20070C39A /* RTViewController.m */, 240 | 9C2994ED1D0A4D6F007722C1 /* RTWebViewController.h */, 241 | 9C2994EE1D0A4D6F007722C1 /* RTWebViewController.m */, 242 | 9C9863FB1F32BDE400CF307B /* RTStatusHiddenViewController.h */, 243 | 9C9863FC1F32BDE400CF307B /* RTStatusHiddenViewController.m */, 244 | ); 245 | name = ViewControllers; 246 | sourceTree = ""; 247 | }; 248 | 9C16AF2D1D097D4200873B86 /* Views */ = { 249 | isa = PBXGroup; 250 | children = ( 251 | 9C16AF2A1D097CEB00873B86 /* RTCustomNavigationBar.h */, 252 | 9C16AF2B1D097CEB00873B86 /* RTCustomNavigationBar.m */, 253 | ); 254 | name = Views; 255 | sourceTree = ""; 256 | }; 257 | F96BE6D2D993D004DBE65F76 /* Pods */ = { 258 | isa = PBXGroup; 259 | children = ( 260 | 4C78C63219178A258FA60E34 /* Pods-RTRootNavigationController_Example.debug.xcconfig */, 261 | C6B0AF5F8FE50A6D2E11BBBC /* Pods-RTRootNavigationController_Example.release.xcconfig */, 262 | F53B590EB877567165CF7290 /* Pods-RTRootNavigationController_Example-RTRootNavigationController_Tests.debug.xcconfig */, 263 | A5267346A018343C32093DA1 /* Pods-RTRootNavigationController_Example-RTRootNavigationController_Tests.release.xcconfig */, 264 | ); 265 | name = Pods; 266 | sourceTree = ""; 267 | }; 268 | /* End PBXGroup section */ 269 | 270 | /* Begin PBXNativeTarget section */ 271 | 6003F589195388D20070C39A /* RTRootNavigationController_Example */ = { 272 | isa = PBXNativeTarget; 273 | buildConfigurationList = 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "RTRootNavigationController_Example" */; 274 | buildPhases = ( 275 | FB44A093851DD2506C7E797E /* [CP] Check Pods Manifest.lock */, 276 | 6003F586195388D20070C39A /* Sources */, 277 | 6003F587195388D20070C39A /* Frameworks */, 278 | 6003F588195388D20070C39A /* Resources */, 279 | 37AD5DB123CD747EA6D19389 /* [CP] Embed Pods Frameworks */, 280 | ); 281 | buildRules = ( 282 | ); 283 | dependencies = ( 284 | ); 285 | name = RTRootNavigationController_Example; 286 | productName = RTRootNavigationController; 287 | productReference = 6003F58A195388D20070C39A /* RTRootNavigationController_Example.app */; 288 | productType = "com.apple.product-type.application"; 289 | }; 290 | 6003F5AD195388D20070C39A /* RTRootNavigationController_Tests */ = { 291 | isa = PBXNativeTarget; 292 | buildConfigurationList = 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "RTRootNavigationController_Tests" */; 293 | buildPhases = ( 294 | 608429C614C9BBE3B2B83B1D /* [CP] Check Pods Manifest.lock */, 295 | 6003F5AA195388D20070C39A /* Sources */, 296 | 6003F5AB195388D20070C39A /* Frameworks */, 297 | 6003F5AC195388D20070C39A /* Resources */, 298 | DBC280C1A032BF55A68C8A16 /* [CP] Embed Pods Frameworks */, 299 | ); 300 | buildRules = ( 301 | ); 302 | dependencies = ( 303 | 6003F5B4195388D20070C39A /* PBXTargetDependency */, 304 | ); 305 | name = RTRootNavigationController_Tests; 306 | productName = RTRootNavigationControllerTests; 307 | productReference = 6003F5AE195388D20070C39A /* RTRootNavigationController_Tests.xctest */; 308 | productType = "com.apple.product-type.bundle.unit-test"; 309 | }; 310 | /* End PBXNativeTarget section */ 311 | 312 | /* Begin PBXProject section */ 313 | 6003F582195388D10070C39A /* Project object */ = { 314 | isa = PBXProject; 315 | attributes = { 316 | CLASSPREFIX = RT; 317 | LastUpgradeCheck = 1000; 318 | ORGANIZATIONNAME = rickytan; 319 | TargetAttributes = { 320 | 6003F5AD195388D20070C39A = { 321 | TestTargetID = 6003F589195388D20070C39A; 322 | }; 323 | }; 324 | }; 325 | buildConfigurationList = 6003F585195388D10070C39A /* Build configuration list for PBXProject "RTRootNavigationController" */; 326 | compatibilityVersion = "Xcode 3.2"; 327 | developmentRegion = English; 328 | hasScannedForEncodings = 0; 329 | knownRegions = ( 330 | English, 331 | en, 332 | Base, 333 | ); 334 | mainGroup = 6003F581195388D10070C39A; 335 | productRefGroup = 6003F58B195388D20070C39A /* Products */; 336 | projectDirPath = ""; 337 | projectRoot = ""; 338 | targets = ( 339 | 6003F589195388D20070C39A /* RTRootNavigationController_Example */, 340 | 6003F5AD195388D20070C39A /* RTRootNavigationController_Tests */, 341 | ); 342 | }; 343 | /* End PBXProject section */ 344 | 345 | /* Begin PBXResourcesBuildPhase section */ 346 | 6003F588195388D20070C39A /* Resources */ = { 347 | isa = PBXResourcesBuildPhase; 348 | buildActionMask = 2147483647; 349 | files = ( 350 | 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */, 351 | 6003F5A9195388D20070C39A /* Images.xcassets in Resources */, 352 | 6003F598195388D20070C39A /* InfoPlist.strings in Resources */, 353 | 9C16AF1F1D09518100873B86 /* Launch.storyboard in Resources */, 354 | ); 355 | runOnlyForDeploymentPostprocessing = 0; 356 | }; 357 | 6003F5AC195388D20070C39A /* Resources */ = { 358 | isa = PBXResourcesBuildPhase; 359 | buildActionMask = 2147483647; 360 | files = ( 361 | 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */, 362 | ); 363 | runOnlyForDeploymentPostprocessing = 0; 364 | }; 365 | /* End PBXResourcesBuildPhase section */ 366 | 367 | /* Begin PBXShellScriptBuildPhase section */ 368 | 37AD5DB123CD747EA6D19389 /* [CP] Embed Pods Frameworks */ = { 369 | isa = PBXShellScriptBuildPhase; 370 | buildActionMask = 2147483647; 371 | files = ( 372 | ); 373 | inputPaths = ( 374 | "${PODS_ROOT}/Target Support Files/Pods-RTRootNavigationController_Example/Pods-RTRootNavigationController_Example-frameworks.sh", 375 | "${BUILT_PRODUCTS_DIR}/RTInteractivePush/RTInteractivePush.framework", 376 | "${BUILT_PRODUCTS_DIR}/RTRootNavigationController/RTRootNavigationController.framework", 377 | ); 378 | name = "[CP] Embed Pods Frameworks"; 379 | outputPaths = ( 380 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RTInteractivePush.framework", 381 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RTRootNavigationController.framework", 382 | ); 383 | runOnlyForDeploymentPostprocessing = 0; 384 | shellPath = /bin/sh; 385 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RTRootNavigationController_Example/Pods-RTRootNavigationController_Example-frameworks.sh\"\n"; 386 | showEnvVarsInLog = 0; 387 | }; 388 | 608429C614C9BBE3B2B83B1D /* [CP] Check Pods Manifest.lock */ = { 389 | isa = PBXShellScriptBuildPhase; 390 | buildActionMask = 2147483647; 391 | files = ( 392 | ); 393 | inputPaths = ( 394 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 395 | "${PODS_ROOT}/Manifest.lock", 396 | ); 397 | name = "[CP] Check Pods Manifest.lock"; 398 | outputPaths = ( 399 | "$(DERIVED_FILE_DIR)/Pods-RTRootNavigationController_Example-RTRootNavigationController_Tests-checkManifestLockResult.txt", 400 | ); 401 | runOnlyForDeploymentPostprocessing = 0; 402 | shellPath = /bin/sh; 403 | 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# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 404 | showEnvVarsInLog = 0; 405 | }; 406 | DBC280C1A032BF55A68C8A16 /* [CP] Embed Pods Frameworks */ = { 407 | isa = PBXShellScriptBuildPhase; 408 | buildActionMask = 2147483647; 409 | files = ( 410 | ); 411 | inputPaths = ( 412 | "${PODS_ROOT}/Target Support Files/Pods-RTRootNavigationController_Example-RTRootNavigationController_Tests/Pods-RTRootNavigationController_Example-RTRootNavigationController_Tests-frameworks.sh", 413 | "${BUILT_PRODUCTS_DIR}/RTInteractivePush/RTInteractivePush.framework", 414 | "${BUILT_PRODUCTS_DIR}/RTRootNavigationController/RTRootNavigationController.framework", 415 | ); 416 | name = "[CP] Embed Pods Frameworks"; 417 | outputPaths = ( 418 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RTInteractivePush.framework", 419 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RTRootNavigationController.framework", 420 | ); 421 | runOnlyForDeploymentPostprocessing = 0; 422 | shellPath = /bin/sh; 423 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RTRootNavigationController_Example-RTRootNavigationController_Tests/Pods-RTRootNavigationController_Example-RTRootNavigationController_Tests-frameworks.sh\"\n"; 424 | showEnvVarsInLog = 0; 425 | }; 426 | FB44A093851DD2506C7E797E /* [CP] Check Pods Manifest.lock */ = { 427 | isa = PBXShellScriptBuildPhase; 428 | buildActionMask = 2147483647; 429 | files = ( 430 | ); 431 | inputPaths = ( 432 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 433 | "${PODS_ROOT}/Manifest.lock", 434 | ); 435 | name = "[CP] Check Pods Manifest.lock"; 436 | outputPaths = ( 437 | "$(DERIVED_FILE_DIR)/Pods-RTRootNavigationController_Example-checkManifestLockResult.txt", 438 | ); 439 | runOnlyForDeploymentPostprocessing = 0; 440 | shellPath = /bin/sh; 441 | 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# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 442 | showEnvVarsInLog = 0; 443 | }; 444 | /* End PBXShellScriptBuildPhase section */ 445 | 446 | /* Begin PBXSourcesBuildPhase section */ 447 | 6003F586195388D20070C39A /* Sources */ = { 448 | isa = PBXSourcesBuildPhase; 449 | buildActionMask = 2147483647; 450 | files = ( 451 | 9C16AF2C1D097CEB00873B86 /* RTCustomNavigationBar.m in Sources */, 452 | 9C7832C41D09152900693F14 /* RTCollectionViewController.m in Sources */, 453 | 9C2994EC1D09B84B007722C1 /* RTItemDetailViewController.m in Sources */, 454 | 6003F59E195388D20070C39A /* RTAppDelegate.m in Sources */, 455 | 6003F5A7195388D20070C39A /* RTViewController.m in Sources */, 456 | 9C16AF251D0957D400873B86 /* RTTableViewController.m in Sources */, 457 | 9C9863FD1F32BDE400CF307B /* RTStatusHiddenViewController.m in Sources */, 458 | 9C7832C11D09111F00693F14 /* RTHideNavigationBarViewController.m in Sources */, 459 | 9C16AF281D095EC700873B86 /* RTStaticTableViewController.m in Sources */, 460 | 9C16AF221D09551E00873B86 /* RTPushRemoveViewController.m in Sources */, 461 | 9C323D281F0E571100A18836 /* CHANGELOG.md in Sources */, 462 | 6003F59A195388D20070C39A /* main.m in Sources */, 463 | 9C2994E91D09B83C007722C1 /* RTItemListViewController.m in Sources */, 464 | 9C2994EF1D0A4D6F007722C1 /* RTWebViewController.m in Sources */, 465 | ); 466 | runOnlyForDeploymentPostprocessing = 0; 467 | }; 468 | 6003F5AA195388D20070C39A /* Sources */ = { 469 | isa = PBXSourcesBuildPhase; 470 | buildActionMask = 2147483647; 471 | files = ( 472 | 6003F5BC195388D20070C39A /* Tests.m in Sources */, 473 | ); 474 | runOnlyForDeploymentPostprocessing = 0; 475 | }; 476 | /* End PBXSourcesBuildPhase section */ 477 | 478 | /* Begin PBXTargetDependency section */ 479 | 6003F5B4195388D20070C39A /* PBXTargetDependency */ = { 480 | isa = PBXTargetDependency; 481 | target = 6003F589195388D20070C39A /* RTRootNavigationController_Example */; 482 | targetProxy = 6003F5B3195388D20070C39A /* PBXContainerItemProxy */; 483 | }; 484 | /* End PBXTargetDependency section */ 485 | 486 | /* Begin PBXVariantGroup section */ 487 | 6003F596195388D20070C39A /* InfoPlist.strings */ = { 488 | isa = PBXVariantGroup; 489 | children = ( 490 | 6003F597195388D20070C39A /* en */, 491 | ); 492 | name = InfoPlist.strings; 493 | sourceTree = ""; 494 | }; 495 | 6003F5B8195388D20070C39A /* InfoPlist.strings */ = { 496 | isa = PBXVariantGroup; 497 | children = ( 498 | 6003F5B9195388D20070C39A /* en */, 499 | ); 500 | name = InfoPlist.strings; 501 | sourceTree = ""; 502 | }; 503 | /* End PBXVariantGroup section */ 504 | 505 | /* Begin XCBuildConfiguration section */ 506 | 6003F5BD195388D20070C39A /* Debug */ = { 507 | isa = XCBuildConfiguration; 508 | buildSettings = { 509 | ALWAYS_SEARCH_USER_PATHS = NO; 510 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 511 | CLANG_CXX_LIBRARY = "libc++"; 512 | CLANG_ENABLE_MODULES = YES; 513 | CLANG_ENABLE_OBJC_ARC = YES; 514 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 515 | CLANG_WARN_BOOL_CONVERSION = YES; 516 | CLANG_WARN_COMMA = YES; 517 | CLANG_WARN_CONSTANT_CONVERSION = YES; 518 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 519 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 520 | CLANG_WARN_EMPTY_BODY = YES; 521 | CLANG_WARN_ENUM_CONVERSION = YES; 522 | CLANG_WARN_INFINITE_RECURSION = YES; 523 | CLANG_WARN_INT_CONVERSION = YES; 524 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 525 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 526 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 527 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 528 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 529 | CLANG_WARN_STRICT_PROTOTYPES = YES; 530 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 531 | CLANG_WARN_UNREACHABLE_CODE = YES; 532 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 533 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 534 | COPY_PHASE_STRIP = NO; 535 | ENABLE_STRICT_OBJC_MSGSEND = YES; 536 | ENABLE_TESTABILITY = YES; 537 | GCC_C_LANGUAGE_STANDARD = gnu99; 538 | GCC_DYNAMIC_NO_PIC = NO; 539 | GCC_NO_COMMON_BLOCKS = YES; 540 | GCC_OPTIMIZATION_LEVEL = 0; 541 | GCC_PREPROCESSOR_DEFINITIONS = ( 542 | "DEBUG=1", 543 | "$(inherited)", 544 | ); 545 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 546 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 547 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 548 | GCC_WARN_UNDECLARED_SELECTOR = YES; 549 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 550 | GCC_WARN_UNUSED_FUNCTION = YES; 551 | GCC_WARN_UNUSED_VARIABLE = YES; 552 | IPHONEOS_DEPLOYMENT_TARGET = 11; 553 | ONLY_ACTIVE_ARCH = YES; 554 | SDKROOT = iphoneos; 555 | TARGETED_DEVICE_FAMILY = "1,2"; 556 | }; 557 | name = Debug; 558 | }; 559 | 6003F5BE195388D20070C39A /* Release */ = { 560 | isa = XCBuildConfiguration; 561 | buildSettings = { 562 | ALWAYS_SEARCH_USER_PATHS = NO; 563 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 564 | CLANG_CXX_LIBRARY = "libc++"; 565 | CLANG_ENABLE_MODULES = YES; 566 | CLANG_ENABLE_OBJC_ARC = YES; 567 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 568 | CLANG_WARN_BOOL_CONVERSION = YES; 569 | CLANG_WARN_COMMA = YES; 570 | CLANG_WARN_CONSTANT_CONVERSION = YES; 571 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 572 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 573 | CLANG_WARN_EMPTY_BODY = YES; 574 | CLANG_WARN_ENUM_CONVERSION = YES; 575 | CLANG_WARN_INFINITE_RECURSION = YES; 576 | CLANG_WARN_INT_CONVERSION = YES; 577 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 578 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 579 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 580 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 581 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 582 | CLANG_WARN_STRICT_PROTOTYPES = YES; 583 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 584 | CLANG_WARN_UNREACHABLE_CODE = YES; 585 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 586 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 587 | COPY_PHASE_STRIP = YES; 588 | ENABLE_NS_ASSERTIONS = NO; 589 | ENABLE_STRICT_OBJC_MSGSEND = YES; 590 | GCC_C_LANGUAGE_STANDARD = gnu99; 591 | GCC_NO_COMMON_BLOCKS = YES; 592 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 593 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 594 | GCC_WARN_UNDECLARED_SELECTOR = YES; 595 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 596 | GCC_WARN_UNUSED_FUNCTION = YES; 597 | GCC_WARN_UNUSED_VARIABLE = YES; 598 | IPHONEOS_DEPLOYMENT_TARGET = 11; 599 | SDKROOT = iphoneos; 600 | TARGETED_DEVICE_FAMILY = "1,2"; 601 | VALIDATE_PRODUCT = YES; 602 | }; 603 | name = Release; 604 | }; 605 | 6003F5C0195388D20070C39A /* Debug */ = { 606 | isa = XCBuildConfiguration; 607 | baseConfigurationReference = 4C78C63219178A258FA60E34 /* Pods-RTRootNavigationController_Example.debug.xcconfig */; 608 | buildSettings = { 609 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 610 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 611 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 612 | GCC_PREFIX_HEADER = "RTRootNavigationController/RTRootNavigationController-Prefix.pch"; 613 | INFOPLIST_FILE = "RTRootNavigationController/RTRootNavigationController-Info.plist"; 614 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 615 | MODULE_NAME = ExampleApp; 616 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}"; 617 | PRODUCT_NAME = "$(TARGET_NAME)"; 618 | WRAPPER_EXTENSION = app; 619 | }; 620 | name = Debug; 621 | }; 622 | 6003F5C1195388D20070C39A /* Release */ = { 623 | isa = XCBuildConfiguration; 624 | baseConfigurationReference = C6B0AF5F8FE50A6D2E11BBBC /* Pods-RTRootNavigationController_Example.release.xcconfig */; 625 | buildSettings = { 626 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 627 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 628 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 629 | GCC_PREFIX_HEADER = "RTRootNavigationController/RTRootNavigationController-Prefix.pch"; 630 | INFOPLIST_FILE = "RTRootNavigationController/RTRootNavigationController-Info.plist"; 631 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 632 | MODULE_NAME = ExampleApp; 633 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}"; 634 | PRODUCT_NAME = "$(TARGET_NAME)"; 635 | WRAPPER_EXTENSION = app; 636 | }; 637 | name = Release; 638 | }; 639 | 6003F5C3195388D20070C39A /* Debug */ = { 640 | isa = XCBuildConfiguration; 641 | baseConfigurationReference = F53B590EB877567165CF7290 /* Pods-RTRootNavigationController_Example-RTRootNavigationController_Tests.debug.xcconfig */; 642 | buildSettings = { 643 | BUNDLE_LOADER = "$(TEST_HOST)"; 644 | FRAMEWORK_SEARCH_PATHS = ( 645 | "$(SDKROOT)/Developer/Library/Frameworks", 646 | "$(inherited)", 647 | "$(DEVELOPER_FRAMEWORKS_DIR)", 648 | ); 649 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 650 | GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch"; 651 | GCC_PREPROCESSOR_DEFINITIONS = ( 652 | "DEBUG=1", 653 | "$(inherited)", 654 | ); 655 | INFOPLIST_FILE = "Tests/Tests-Info.plist"; 656 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 657 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}"; 658 | PRODUCT_NAME = "$(TARGET_NAME)"; 659 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RTRootNavigationController_Example.app/RTRootNavigationController_Example"; 660 | WRAPPER_EXTENSION = xctest; 661 | }; 662 | name = Debug; 663 | }; 664 | 6003F5C4195388D20070C39A /* Release */ = { 665 | isa = XCBuildConfiguration; 666 | baseConfigurationReference = A5267346A018343C32093DA1 /* Pods-RTRootNavigationController_Example-RTRootNavigationController_Tests.release.xcconfig */; 667 | buildSettings = { 668 | BUNDLE_LOADER = "$(TEST_HOST)"; 669 | FRAMEWORK_SEARCH_PATHS = ( 670 | "$(SDKROOT)/Developer/Library/Frameworks", 671 | "$(inherited)", 672 | "$(DEVELOPER_FRAMEWORKS_DIR)", 673 | ); 674 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 675 | GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch"; 676 | INFOPLIST_FILE = "Tests/Tests-Info.plist"; 677 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 678 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}"; 679 | PRODUCT_NAME = "$(TARGET_NAME)"; 680 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RTRootNavigationController_Example.app/RTRootNavigationController_Example"; 681 | WRAPPER_EXTENSION = xctest; 682 | }; 683 | name = Release; 684 | }; 685 | /* End XCBuildConfiguration section */ 686 | 687 | /* Begin XCConfigurationList section */ 688 | 6003F585195388D10070C39A /* Build configuration list for PBXProject "RTRootNavigationController" */ = { 689 | isa = XCConfigurationList; 690 | buildConfigurations = ( 691 | 6003F5BD195388D20070C39A /* Debug */, 692 | 6003F5BE195388D20070C39A /* Release */, 693 | ); 694 | defaultConfigurationIsVisible = 0; 695 | defaultConfigurationName = Release; 696 | }; 697 | 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "RTRootNavigationController_Example" */ = { 698 | isa = XCConfigurationList; 699 | buildConfigurations = ( 700 | 6003F5C0195388D20070C39A /* Debug */, 701 | 6003F5C1195388D20070C39A /* Release */, 702 | ); 703 | defaultConfigurationIsVisible = 0; 704 | defaultConfigurationName = Release; 705 | }; 706 | 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "RTRootNavigationController_Tests" */ = { 707 | isa = XCConfigurationList; 708 | buildConfigurations = ( 709 | 6003F5C3195388D20070C39A /* Debug */, 710 | 6003F5C4195388D20070C39A /* Release */, 711 | ); 712 | defaultConfigurationIsVisible = 0; 713 | defaultConfigurationName = Release; 714 | }; 715 | /* End XCConfigurationList section */ 716 | }; 717 | rootObject = 6003F582195388D10070C39A /* Project object */; 718 | } 719 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController.xcodeproj/xcshareddata/xcschemes/RTRootNavigationController-Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/Images.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/RTRootNavigationController/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/RTRootNavigationController/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "8.0", 8 | "subtype" : "736h", 9 | "scale" : "3x" 10 | }, 11 | { 12 | "orientation" : "portrait", 13 | "idiom" : "iphone", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "8.0", 16 | "subtype" : "667h", 17 | "scale" : "2x" 18 | }, 19 | { 20 | "orientation" : "portrait", 21 | "idiom" : "iphone", 22 | "extent" : "full-screen", 23 | "minimum-system-version" : "7.0", 24 | "scale" : "2x" 25 | }, 26 | { 27 | "orientation" : "portrait", 28 | "idiom" : "iphone", 29 | "extent" : "full-screen", 30 | "minimum-system-version" : "7.0", 31 | "subtype" : "retina4", 32 | "scale" : "2x" 33 | } 34 | ], 35 | "info" : { 36 | "version" : 1, 37 | "author" : "xcode" 38 | } 39 | } -------------------------------------------------------------------------------- /Example/RTRootNavigationController/Images.xcassets/about.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "about.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Example/RTRootNavigationController/Images.xcassets/about.imageset/about.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickytan/RTRootNavigationController/2ab3cf2ea416c409898a02d869697a9010bb5971/Example/RTRootNavigationController/Images.xcassets/about.imageset/about.pdf -------------------------------------------------------------------------------- /Example/RTRootNavigationController/Images.xcassets/add_user_male.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "add_user_male.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Example/RTRootNavigationController/Images.xcassets/add_user_male.imageset/add_user_male.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickytan/RTRootNavigationController/2ab3cf2ea416c409898a02d869697a9010bb5971/Example/RTRootNavigationController/Images.xcassets/add_user_male.imageset/add_user_male.pdf -------------------------------------------------------------------------------- /Example/RTRootNavigationController/Images.xcassets/apple.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "apple@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/RTRootNavigationController/Images.xcassets/apple.imageset/apple@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickytan/RTRootNavigationController/2ab3cf2ea416c409898a02d869697a9010bb5971/Example/RTRootNavigationController/Images.xcassets/apple.imageset/apple@2x.png -------------------------------------------------------------------------------- /Example/RTRootNavigationController/Images.xcassets/back.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "back.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "template" 14 | } 15 | } -------------------------------------------------------------------------------- /Example/RTRootNavigationController/Images.xcassets/back.imageset/back.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickytan/RTRootNavigationController/2ab3cf2ea416c409898a02d869697a9010bb5971/Example/RTRootNavigationController/Images.xcassets/back.imageset/back.pdf -------------------------------------------------------------------------------- /Example/RTRootNavigationController/Launch.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 27 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // RTAppDelegate.h 3 | // RTRootNavigationController 4 | // 5 | // Created by rickytan on 06/08/2016. 6 | // Copyright (c) 2016 rickytan. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @interface RTAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // RTAppDelegate.m 3 | // RTRootNavigationController 4 | // 5 | // Created by rickytan on 06/08/2016. 6 | // Copyright (c) 2016 rickytan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "RTAppDelegate.h" 12 | 13 | @interface RTTabBarController : UITabBarController 14 | @end 15 | 16 | @implementation RTTabBarController 17 | 18 | - (BOOL)prefersStatusBarHidden 19 | { 20 | return self.selectedViewController.prefersStatusBarHidden; 21 | } 22 | 23 | - (UIStatusBarAnimation)preferredStatusBarUpdateAnimation 24 | { 25 | return self.selectedViewController.preferredStatusBarUpdateAnimation; 26 | } 27 | 28 | - (UIStatusBarStyle)preferredStatusBarStyle 29 | { 30 | return self.selectedViewController.preferredStatusBarStyle; 31 | } 32 | 33 | @end 34 | 35 | @implementation RTAppDelegate 36 | 37 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 38 | { 39 | // Override point for customization after application launch. 40 | /* 41 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 42 | UIStoryboard *story = [UIStoryboard storyboardWithName:@"Main" 43 | bundle:nil]; 44 | UITabBarController *tabController = [[RTTabBarController alloc] init]; 45 | // tabController.tabBar.translucent = NO; 46 | if (YES) { 47 | tabController.viewControllers = @[[[RTContainerNavigationController alloc] initWithRootViewController:[story instantiateViewControllerWithIdentifier:@"Root"]], 48 | [[RTContainerNavigationController alloc] initWithRootViewController:[story instantiateViewControllerWithIdentifier:@"Remove"]], 49 | [[RTContainerNavigationController alloc] initWithRootViewController:[story instantiateViewControllerWithIdentifier:@"Scroll"]], 50 | [[RTContainerNavigationController alloc] initWithRootViewController:[story instantiateViewControllerWithIdentifier:@"Table"]], 51 | [[RTContainerNavigationController alloc] initWithRootViewController:[story instantiateViewControllerWithIdentifier:@"Status"]]]; 52 | self.window.rootViewController = [[RTRootNavigationController alloc] initWithRootViewControllerNoWrapping:tabController]; 53 | } 54 | else { 55 | tabController.viewControllers = @[[[RTRootNavigationController alloc] initWithRootViewController:[story instantiateViewControllerWithIdentifier:@"Root"]], 56 | [[RTRootNavigationController alloc] initWithRootViewController:[story instantiateViewControllerWithIdentifier:@"Remove"]], 57 | [[RTRootNavigationController alloc] initWithRootViewController:[story instantiateViewControllerWithIdentifier:@"Scroll"]], 58 | [[RTRootNavigationController alloc] initWithRootViewController:[story instantiateViewControllerWithIdentifier:@"Table"]]]; 59 | self.window.rootViewController = tabController; 60 | } 61 | [self.window makeKeyAndVisible]; 62 | */ 63 | return YES; 64 | } 65 | 66 | - (void)applicationWillResignActive:(UIApplication *)application 67 | { 68 | // 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. 69 | // 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. 70 | } 71 | 72 | - (void)applicationDidEnterBackground:(UIApplication *)application 73 | { 74 | // 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. 75 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 76 | } 77 | 78 | - (void)applicationWillEnterForeground:(UIApplication *)application 79 | { 80 | // 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. 81 | } 82 | 83 | - (void)applicationDidBecomeActive:(UIApplication *)application 84 | { 85 | // 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. 86 | } 87 | 88 | - (void)applicationWillTerminate:(UIApplication *)application 89 | { 90 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 91 | } 92 | 93 | @end 94 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTCollectionViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RTCollectionViewController.h 3 | // RTRootNavigationController 4 | // 5 | // Created by ricky on 16/6/9. 6 | // Copyright © 2016年 rickytan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface RTCollectionViewController : UICollectionViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTCollectionViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // RTCollectionViewController.m 3 | // RTRootNavigationController 4 | // 5 | // Created by ricky on 16/6/9. 6 | // Copyright © 2016年 rickytan. All rights reserved. 7 | // 8 | 9 | #import "RTCollectionViewController.h" 10 | 11 | @interface RTCollectionViewController () 12 | 13 | @end 14 | 15 | @implementation RTCollectionViewController 16 | 17 | static NSString * const reuseIdentifier = @"Cell"; 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | 22 | // Uncomment the following line to preserve selection between presentations 23 | // self.clearsSelectionOnViewWillAppear = NO; 24 | 25 | // Register cell classes 26 | 27 | // Do any additional setup after loading the view. 28 | } 29 | 30 | - (void)didReceiveMemoryWarning { 31 | [super didReceiveMemoryWarning]; 32 | // Dispose of any resources that can be recreated. 33 | } 34 | 35 | /* 36 | #pragma mark - Navigation 37 | 38 | // In a storyboard-based application, you will often want to do a little preparation before navigation 39 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 40 | // Get the new view controller using [segue destinationViewController]. 41 | // Pass the selected object to the new view controller. 42 | } 43 | */ 44 | 45 | #pragma mark 46 | 47 | - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { 48 | return 1; 49 | } 50 | 51 | 52 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { 53 | return 50; 54 | } 55 | 56 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 57 | UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath]; 58 | 59 | // Configure the cell 60 | ((UILabel *)[[cell contentView] viewWithTag:100]).text = [NSString stringWithFormat:@"%@", @(indexPath.item)]; 61 | 62 | return cell; 63 | } 64 | 65 | #pragma mark 66 | 67 | /* 68 | // Uncomment this method to specify if the specified item should be highlighted during tracking 69 | - (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath { 70 | return YES; 71 | } 72 | */ 73 | 74 | /* 75 | // Uncomment this method to specify if the specified item should be selected 76 | - (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath { 77 | return YES; 78 | } 79 | */ 80 | 81 | /* 82 | // Uncomment these methods to specify if an action menu should be displayed for the specified item, and react to actions performed on the item 83 | - (BOOL)collectionView:(UICollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath { 84 | return NO; 85 | } 86 | 87 | - (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { 88 | return NO; 89 | } 90 | 91 | - (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { 92 | 93 | } 94 | */ 95 | 96 | @end 97 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTCustomNavigationBar.h: -------------------------------------------------------------------------------- 1 | // 2 | // RTCustomNavigationBar.h 3 | // RTRootNavigationController 4 | // 5 | // Created by ricky on 16/6/9. 6 | // Copyright © 2016年 rickytan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface RTCustomNavigationBar : UINavigationBar 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTCustomNavigationBar.m: -------------------------------------------------------------------------------- 1 | // 2 | // RTCustomNavigationBar.m 3 | // RTRootNavigationController 4 | // 5 | // Created by ricky on 16/6/9. 6 | // Copyright © 2016年 rickytan. All rights reserved. 7 | // 8 | 9 | #import "RTCustomNavigationBar.h" 10 | 11 | @implementation RTCustomNavigationBar 12 | 13 | - (void)drawRect:(CGRect)rect 14 | { 15 | UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRect:rect]; 16 | bezierPath.lineWidth = 4.f; 17 | [[UIColor orangeColor] setStroke]; 18 | [[UIColor whiteColor] setFill]; 19 | [bezierPath fill]; 20 | [bezierPath stroke]; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTHideNavigationBarViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RTHideNavigationBarViewController.h 3 | // RTRootNavigationController 4 | // 5 | // Created by ricky on 16/6/9. 6 | // Copyright © 2016年 rickytan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface RTHideNavigationBarViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTHideNavigationBarViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // RTHideNavigationBarViewController.m 3 | // RTRootNavigationController 4 | // 5 | // Created by ricky on 16/6/9. 6 | // Copyright © 2016年 rickytan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "RTHideNavigationBarViewController.h" 12 | #import "RTCollectionViewController.h" 13 | 14 | @interface RTHideNavigationBarViewController () 15 | 16 | @end 17 | 18 | @implementation RTHideNavigationBarViewController 19 | 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | // Do any additional setup after loading the view. 23 | self.navigationController.navigationBarHidden = YES; 24 | #if RT_INTERACTIVE_PUSH 25 | self.rt_navigationController.rt_enableInteractivePush = YES; 26 | #endif 27 | } 28 | 29 | - (void)didReceiveMemoryWarning { 30 | [super didReceiveMemoryWarning]; 31 | // Dispose of any resources that can be recreated. 32 | } 33 | 34 | - (void)didMoveToParentViewController:(UIViewController *)parent 35 | { 36 | [super didMoveToParentViewController:parent]; 37 | self.navigationController.navigationBarHidden = YES; 38 | } 39 | 40 | - (IBAction)onBack:(id)sender { 41 | [self.navigationController popViewControllerAnimated:YES]; 42 | } 43 | 44 | #if RT_INTERACTIVE_PUSH 45 | - (UIViewController *)rt_nextSiblingController 46 | { 47 | return [self.storyboard instantiateViewControllerWithIdentifier:@"Scroll"]; 48 | } 49 | #endif 50 | 51 | /* 52 | #pragma mark - Navigation 53 | 54 | // In a storyboard-based application, you will often want to do a little preparation before navigation 55 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 56 | // Get the new view controller using [segue destinationViewController]. 57 | // Pass the selected object to the new view controller. 58 | } 59 | */ 60 | 61 | - (NSArray> *)previewActionItems 62 | { 63 | return @[[UIPreviewAction actionWithTitle:@"Default" 64 | style:UIPreviewActionStyleDefault 65 | handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) { 66 | 67 | }], 68 | [UIPreviewAction actionWithTitle:@"Selected" 69 | style:UIPreviewActionStyleSelected 70 | handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) { 71 | 72 | }], 73 | [UIPreviewAction actionWithTitle:@"Destructive" 74 | style:UIPreviewActionStyleDestructive 75 | handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) { 76 | 77 | }] 78 | ]; 79 | } 80 | 81 | @end 82 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTItemDetailViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RTItemDetailViewController.h 3 | // RTRootNavigationController 4 | // 5 | // Created by ricky on 16/6/9. 6 | // Copyright © 2016年 rickytan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface RTItemDetailViewController : UIViewController 12 | @property (weak, nonatomic) IBOutlet UIImageView *itemImageView; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTItemDetailViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // RTItemDetailViewController.m 3 | // RTRootNavigationController 4 | // 5 | // Created by ricky on 16/6/9. 6 | // Copyright © 2016年 rickytan. All rights reserved. 7 | // 8 | 9 | #import "RTItemDetailViewController.h" 10 | 11 | @interface RTItemDetailViewController () 12 | 13 | @end 14 | 15 | @implementation RTItemDetailViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view. 20 | } 21 | 22 | - (void)didReceiveMemoryWarning { 23 | [super didReceiveMemoryWarning]; 24 | // Dispose of any resources that can be recreated. 25 | } 26 | 27 | - (BOOL)prefersHomeIndicatorAutoHidden 28 | { 29 | return YES; 30 | } 31 | /* 32 | #pragma mark - Navigation 33 | 34 | // In a storyboard-based application, you will often want to do a little preparation before navigation 35 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 36 | // Get the new view controller using [segue destinationViewController]. 37 | // Pass the selected object to the new view controller. 38 | } 39 | */ 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTItemListViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RTItemListViewController.h 3 | // RTRootNavigationController 4 | // 5 | // Created by ricky on 16/6/9. 6 | // Copyright © 2016年 rickytan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface RTItemListViewController : UICollectionViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTItemListViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // RTItemListViewController.m 3 | // RTRootNavigationController 4 | // 5 | // Created by ricky on 16/6/9. 6 | // Copyright © 2016年 rickytan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "RTItemListViewController.h" 12 | #import "RTItemDetailViewController.h" 13 | 14 | @interface RTItemListViewController () 15 | 16 | @end 17 | 18 | @implementation RTItemListViewController 19 | 20 | static NSString * const reuseIdentifier = @"Cell"; 21 | 22 | - (void)viewDidLoad { 23 | [super viewDidLoad]; 24 | 25 | // Uncomment the following line to preserve selection between presentations 26 | // self.clearsSelectionOnViewWillAppear = NO; 27 | 28 | // Do any additional setup after loading the view. 29 | } 30 | 31 | - (void)viewWillAppear:(BOOL)animated 32 | { 33 | [super viewWillAppear:animated]; 34 | ((UICollectionViewFlowLayout *)self.collectionViewLayout).itemSize = CGSizeMake((self.view.bounds.size.width - 10 * 3) / 2, 150); 35 | } 36 | 37 | - (void)didReceiveMemoryWarning { 38 | [super didReceiveMemoryWarning]; 39 | // Dispose of any resources that can be recreated. 40 | } 41 | 42 | 43 | #pragma mark - Navigation 44 | 45 | // In a storyboard-based application, you will often want to do a little preparation before navigation 46 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 47 | // Get the new view controller using [segue destinationViewController]. 48 | // Pass the selected object to the new view controller. 49 | self.navigationController.delegate = self; 50 | } 51 | 52 | 53 | #pragma mark 54 | 55 | - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { 56 | return 1; 57 | } 58 | 59 | 60 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { 61 | return 20; 62 | } 63 | 64 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 65 | UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath]; 66 | 67 | // Configure the cell 68 | 69 | return cell; 70 | } 71 | 72 | #pragma mark - UINavigationController Delegate 73 | 74 | - (id)navigationController:(UINavigationController *)navigationController 75 | animationControllerForOperation:(UINavigationControllerOperation)operation 76 | fromViewController:(UIViewController *)fromVC 77 | toViewController:(UIViewController *)toVC 78 | { 79 | if (operation == UINavigationControllerOperationPush) 80 | return self; 81 | return nil; 82 | } 83 | 84 | - (NSTimeInterval)transitionDuration:(nullable id )transitionContext 85 | { 86 | return UINavigationControllerHideShowBarDuration; 87 | } 88 | 89 | - (void)animateTransition:(id )transitionContext 90 | { 91 | UIView *containerView = [transitionContext containerView]; 92 | RTContainerController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; 93 | RTContainerController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; 94 | 95 | [containerView addSubview:toVC.view]; 96 | 97 | // following is required! 98 | [containerView setNeedsLayout]; 99 | [containerView layoutIfNeeded]; 100 | 101 | toVC.view.alpha = 0.f; 102 | 103 | NSIndexPath *selected = ((RTItemListViewController *)fromVC.contentViewController).collectionView.indexPathsForSelectedItems.firstObject; 104 | UICollectionViewCell *cell = [((RTItemListViewController *)fromVC.contentViewController).collectionView cellForItemAtIndexPath:selected]; 105 | CGRect frame = [toVC.contentViewController.view convertRect:cell.frame 106 | fromView:cell.superview]; 107 | CGRect finalFrame = ((RTItemDetailViewController *)toVC.contentViewController).itemImageView.frame; 108 | ((RTItemDetailViewController *)toVC.contentViewController).itemImageView.frame = frame; 109 | [UIView transitionWithView:containerView 110 | duration:[self transitionDuration:transitionContext] 111 | options:UIViewAnimationOptionCurveEaseOut 112 | animations:^{ 113 | toVC.view.alpha = 1.f; 114 | ((RTItemDetailViewController *)toVC.contentViewController).itemImageView.frame = finalFrame; 115 | } 116 | completion:^(BOOL finished) { 117 | if (finished) { 118 | [[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view removeFromSuperview]; 119 | } 120 | [transitionContext completeTransition:finished]; 121 | }]; 122 | } 123 | 124 | @end 125 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTPushRemoveViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RTPushRemoveViewController.h 3 | // RTRootNavigationController 4 | // 5 | // Created by ricky on 16/6/9. 6 | // Copyright © 2016年 rickytan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface RTPushRemoveViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTPushRemoveViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // RTPushRemoveViewController.m 3 | // RTRootNavigationController 4 | // 5 | // Created by ricky on 16/6/9. 6 | // Copyright © 2016年 rickytan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "RTPushRemoveViewController.h" 12 | #import "RTViewController.h" 13 | 14 | @interface RTPushRemoveViewController () 15 | @property (weak, nonatomic) IBOutlet UISwitch *animatedSwitch; 16 | 17 | @end 18 | 19 | @implementation RTPushRemoveViewController 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | // Do any additional setup after loading the view. 24 | } 25 | 26 | - (void)didReceiveMemoryWarning { 27 | [super didReceiveMemoryWarning]; 28 | // Dispose of any resources that can be recreated. 29 | } 30 | 31 | - (IBAction)onPush:(id)sender { 32 | [self.rt_navigationController pushViewController:[[RTViewController alloc] init] 33 | animated:self.animatedSwitch.on 34 | complete:^(BOOL finished) { 35 | [self.rt_navigationController removeViewController:self]; 36 | }]; 37 | } 38 | 39 | /* 40 | #pragma mark - Navigation 41 | 42 | // In a storyboard-based application, you will often want to do a little preparation before navigation 43 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 44 | // Get the new view controller using [segue destinationViewController]. 45 | // Pass the selected object to the new view controller. 46 | } 47 | */ 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTRootNavigationController-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | RootNav 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | Launch 29 | UIMainStoryboardFile 30 | Main 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | UISupportedInterfaceOrientations~ipad 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationPortraitUpsideDown 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTRootNavigationController-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | @import UIKit; 15 | @import Foundation; 16 | #endif 17 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTStaticTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RTStaticTableViewController.h 3 | // RTRootNavigationController 4 | // 5 | // Created by ricky on 16/6/9. 6 | // Copyright © 2016年 rickytan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface RTStaticTableViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTStaticTableViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // RTStaticTableViewController.m 3 | // RTRootNavigationController 4 | // 5 | // Created by ricky on 16/6/9. 6 | // Copyright © 2016年 rickytan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "RTStaticTableViewController.h" 12 | #import "RTCustomNavigationBar.h" 13 | 14 | @interface RTStaticTableViewController () 15 | 16 | @end 17 | 18 | @implementation RTStaticTableViewController 19 | 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | 23 | } 24 | 25 | - (void)didReceiveMemoryWarning { 26 | [super didReceiveMemoryWarning]; 27 | // Dispose of any resources that can be recreated. 28 | } 29 | 30 | - (IBAction)popToRoot:(UIStoryboardSegue *)segue 31 | { 32 | 33 | } 34 | 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTStatusHiddenViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RTStatusHiddenViewController.h 3 | // RTRootNavigationController 4 | // 5 | // Created by Ricky on 2017/8/3. 6 | // Copyright © 2017年 rickytan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface RTStatusHiddenViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTStatusHiddenViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // RTStatusHiddenViewController.m 3 | // RTRootNavigationController 4 | // 5 | // Created by Ricky on 2017/8/3. 6 | // Copyright © 2017年 rickytan. All rights reserved. 7 | // 8 | 9 | #import "RTStatusHiddenViewController.h" 10 | 11 | @interface RTStatusHiddenViewController () 12 | 13 | @end 14 | 15 | @implementation RTStatusHiddenViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view. 20 | } 21 | 22 | - (void)didReceiveMemoryWarning { 23 | [super didReceiveMemoryWarning]; 24 | // Dispose of any resources that can be recreated. 25 | } 26 | 27 | - (BOOL)prefersStatusBarHidden 28 | { 29 | return YES; 30 | } 31 | 32 | - (UIStatusBarAnimation)preferredStatusBarUpdateAnimation 33 | { 34 | return UIStatusBarAnimationSlide; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RTTableViewController.h 3 | // RTRootNavigationController 4 | // 5 | // Created by ricky on 16/6/9. 6 | // Copyright © 2016年 rickytan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface RTTableViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTTableViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // RTTableViewController.m 3 | // RTRootNavigationController 4 | // 5 | // Created by ricky on 16/6/9. 6 | // Copyright © 2016年 rickytan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "RTTableViewController.h" 12 | #import "RTCustomNavigationBar.h" 13 | 14 | @interface RTTableViewController () 15 | 16 | @end 17 | 18 | @implementation RTTableViewController 19 | 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | 23 | // Uncomment the following line to preserve selection between presentations. 24 | // self.clearsSelectionOnViewWillAppear = NO; 25 | 26 | self.navigationController.navigationBar.tintColor = self.view.tintColor; 27 | self.navigationController.navigationBar.translucent = YES; 28 | self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName: self.view.tintColor}; 29 | } 30 | 31 | - (void)didReceiveMemoryWarning { 32 | [super didReceiveMemoryWarning]; 33 | // Dispose of any resources that can be recreated. 34 | } 35 | 36 | - (Class)rt_navigationBarClass 37 | { 38 | return [RTCustomNavigationBar class]; 39 | } 40 | 41 | #pragma mark - Table view data source 42 | 43 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 44 | return 1; 45 | } 46 | 47 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 48 | return 20; 49 | } 50 | 51 | 52 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 53 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath]; 54 | 55 | // Configure the cell... 56 | cell.textLabel.text = [NSString stringWithFormat:@"Row: %ld", (long)indexPath.row]; 57 | 58 | return cell; 59 | } 60 | 61 | - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView 62 | { 63 | CGPoint point = [scrollView.panGestureRecognizer velocityInView:scrollView]; 64 | if (point.y > 120.0) { 65 | [self.navigationController setNavigationBarHidden:NO 66 | animated:YES]; 67 | } 68 | else if (point.y < -120.0) { 69 | [self.navigationController setNavigationBarHidden:YES 70 | animated:YES]; 71 | } 72 | } 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RTViewController.h 3 | // RTRootNavigationController 4 | // 5 | // Created by rickytan on 06/08/2016. 6 | // Copyright (c) 2016 rickytan. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @interface RTViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // RTViewController.m 3 | // RTRootNavigationController 4 | // 5 | // Created by rickytan on 06/08/2016. 6 | // Copyright (c) 2016 rickytan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "RTViewController.h" 12 | 13 | @interface RTViewController () 14 | 15 | @end 16 | 17 | @implementation RTViewController 18 | 19 | - (void)viewDidLoad 20 | { 21 | [super viewDidLoad]; 22 | // Do any additional setup after loading the view, typically from a nib. 23 | self.title = @"Test VC"; 24 | self.view.backgroundColor = [UIColor whiteColor]; 25 | self.navigationController.navigationBar.barTintColor = [UIColor blueColor]; 26 | self.navigationController.navigationBar.tintColor = [UIColor whiteColor]; 27 | self.navigationController.navigationBar.translucent = YES; 28 | [self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor whiteColor]}]; 29 | } 30 | 31 | - (BOOL)canBecomeFirstResponder 32 | { 33 | return YES; 34 | } 35 | 36 | - (UIStatusBarStyle)preferredStatusBarStyle 37 | { 38 | return UIStatusBarStyleLightContent; 39 | } 40 | 41 | - (UIBarButtonItem *)rt_customBackItemWithTarget:(id)target action:(SEL)action 42 | { 43 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 44 | [button setImage:[UIImage imageNamed:@"back"] forState:UIControlStateNormal]; 45 | [button sizeToFit]; 46 | [button addTarget:target 47 | action:action 48 | forControlEvents:UIControlEventTouchUpInside]; 49 | return [[UIBarButtonItem alloc] initWithCustomView:button]; 50 | } 51 | 52 | - (void)didReceiveMemoryWarning 53 | { 54 | [super didReceiveMemoryWarning]; 55 | // Dispose of any resources that can be recreated. 56 | } 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTWebViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RTWebViewController.h 3 | // RTRootNavigationController 4 | // 5 | // Created by ricky on 16/6/10. 6 | // Copyright © 2016年 rickytan. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface RTWebViewController : UIViewController 13 | @property (nonatomic, readonly, strong) WKWebView *webView; 14 | @end 15 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/RTWebViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // RTWebViewController.m 3 | // RTRootNavigationController 4 | // 5 | // Created by ricky on 16/6/10. 6 | // Copyright © 2016年 rickytan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "RTWebViewController.h" 12 | 13 | @interface RTWebViewController () 14 | @property (nonatomic, strong) WKWebView *webView; 15 | @property (nonatomic, strong) UILabel *indicateLabel; 16 | @property (nonatomic, strong) UIActivityIndicatorView *spinnerView; 17 | @end 18 | 19 | @implementation RTWebViewController 20 | 21 | - (void)loadView 22 | { 23 | [super loadView]; 24 | self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds]; 25 | self.webView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; 26 | self.webView.navigationDelegate = self; 27 | self.webView.allowsBackForwardNavigationGestures = YES; 28 | [self.view addSubview:self.webView]; 29 | 30 | self.indicateLabel = [[UILabel alloc] init]; 31 | self.indicateLabel.font = [UIFont systemFontOfSize:14.f]; 32 | self.indicateLabel.textColor = [UIColor whiteColor]; 33 | self.indicateLabel.numberOfLines = 2; 34 | self.indicateLabel.textAlignment = NSTextAlignmentCenter; 35 | self.indicateLabel.text = @"Site provided by:\n"; 36 | [self.indicateLabel sizeToFit]; 37 | self.indicateLabel.translatesAutoresizingMaskIntoConstraints = NO; 38 | [self.webView insertSubview:self.indicateLabel 39 | belowSubview:self.webView.scrollView]; 40 | 41 | [self.webView addConstraints:@[[NSLayoutConstraint constraintWithItem:self.indicateLabel 42 | attribute:NSLayoutAttributeTop 43 | relatedBy:NSLayoutRelationEqual 44 | toItem:self.webView 45 | attribute:NSLayoutAttributeTop 46 | multiplier:1.0 47 | constant:16.f], 48 | [NSLayoutConstraint constraintWithItem:self.indicateLabel 49 | attribute:NSLayoutAttributeCenterX 50 | relatedBy:NSLayoutRelationEqual 51 | toItem:self.webView 52 | attribute:NSLayoutAttributeCenterX 53 | multiplier:1.0 54 | constant:0.f]]]; 55 | } 56 | 57 | - (void)viewDidLoad { 58 | [super viewDidLoad]; 59 | // Do any additional setup after loading the view. 60 | self.navigationController.toolbarHidden = NO; 61 | self.navigationController.toolbar.translucent = NO; 62 | 63 | [self.webView.gestureRecognizers enumerateObjectsUsingBlock:^(__kindof UIGestureRecognizer * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 64 | if ([obj isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]) { 65 | [self.rt_navigationController.interactivePopGestureRecognizer requireGestureRecognizerToFail:obj]; 66 | *stop = YES; 67 | } 68 | }]; 69 | 70 | self.spinnerView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; 71 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:self.spinnerView]; 72 | 73 | UIBarButtonItem *backward = [[UIBarButtonItem alloc] initWithTitle:@"<" 74 | style:UIBarButtonItemStylePlain 75 | target:self 76 | action:@selector(onBackward:)]; 77 | backward.enabled = NO; 78 | UIBarButtonItem *forward = [[UIBarButtonItem alloc] initWithTitle:@">" 79 | style:UIBarButtonItemStylePlain 80 | target:self 81 | action:@selector(onForward:)]; 82 | forward.enabled = NO; 83 | UIBarButtonItem *refresh = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh 84 | target:self 85 | action:@selector(onRefresh:)]; 86 | UIBarButtonItem *share = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction 87 | target:self 88 | action:@selector(onShare:)]; 89 | self.toolbarItems = @[backward, 90 | [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace 91 | target:nil 92 | action:NULL], 93 | forward, 94 | [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace 95 | target:nil 96 | action:NULL], 97 | refresh, 98 | [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace 99 | target:nil 100 | action:NULL], 101 | share]; 102 | 103 | 104 | [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://github.com"]]]; 105 | } 106 | 107 | - (UIStatusBarStyle)preferredStatusBarStyle 108 | { 109 | return UIStatusBarStyleLightContent; 110 | } 111 | 112 | - (void)didReceiveMemoryWarning { 113 | [super didReceiveMemoryWarning]; 114 | // Dispose of any resources that can be recreated. 115 | } 116 | 117 | - (void)onBackward:(id)sender 118 | { 119 | [self.webView goBack]; 120 | } 121 | 122 | - (void)onForward:(id)sender 123 | { 124 | [self.webView goForward]; 125 | } 126 | 127 | - (void)onRefresh:(id)sender 128 | { 129 | [self.webView reload]; 130 | } 131 | 132 | - (void)onShare:(id)sender 133 | { 134 | 135 | } 136 | 137 | - (IBAction)onToggleToolbar:(id)sender { 138 | [self.navigationController setToolbarHidden:!self.navigationController.isToolbarHidden 139 | animated:YES]; 140 | } 141 | 142 | - (UIBarButtonItem *)rt_customBackItemWithTarget:(id)target action:(SEL)action 143 | { 144 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 145 | [button setImage:[UIImage imageNamed:@"back"] forState:UIControlStateNormal]; 146 | [button sizeToFit]; 147 | [button addTarget:target 148 | action:action 149 | forControlEvents:UIControlEventTouchUpInside]; 150 | return [[UIBarButtonItem alloc] initWithCustomView:button]; 151 | } 152 | 153 | #pragma mark - UIWebView Delegate 154 | 155 | - (void)webViewDidStartLoad:(UIWebView *)webView 156 | { 157 | [self.spinnerView startAnimating]; 158 | } 159 | 160 | - (void)webViewDidFinishLoad:(UIWebView *)webView 161 | { 162 | [self.spinnerView stopAnimating]; 163 | self.indicateLabel.text = [NSString stringWithFormat:@"Site provided by:\n%@", webView.request.URL.host]; 164 | self.title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"]; 165 | 166 | self.toolbarItems[0].enabled = webView.canGoBack; 167 | self.toolbarItems[2].enabled = webView.canGoForward; 168 | } 169 | 170 | - (void)webView:(UIWebView *)webView 171 | didFailLoadWithError:(NSError *)error 172 | { 173 | [self.spinnerView stopAnimating]; 174 | } 175 | 176 | #pragma mark - WKUIDelegate 177 | 178 | - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation 179 | { 180 | [self.spinnerView startAnimating]; 181 | } 182 | 183 | - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation 184 | { 185 | [self.spinnerView stopAnimating]; 186 | self.indicateLabel.text = [NSString stringWithFormat:@"Site provided by:\n%@", webView.URL.host]; 187 | self.title = webView.title; 188 | 189 | self.toolbarItems[0].enabled = webView.canGoBack; 190 | self.toolbarItems[2].enabled = webView.canGoForward; 191 | } 192 | 193 | - (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error 194 | { 195 | [self.spinnerView stopAnimating]; 196 | } 197 | 198 | @end 199 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/RTRootNavigationController/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // RTRootNavigationController 4 | // 5 | // Created by rickytan on 06/08/2016. 6 | // Copyright (c) 2016 rickytan. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | #import "RTAppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) 13 | { 14 | @autoreleasepool { 15 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([RTAppDelegate class])); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Example/Tests/Tests-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 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/Tests/Tests-Prefix.pch: -------------------------------------------------------------------------------- 1 | // The contents of this file are implicitly included at the beginning of every test case source file. 2 | 3 | #ifdef __OBJC__ 4 | 5 | 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /Example/Tests/Tests.m: -------------------------------------------------------------------------------- 1 | // 2 | // RTRootNavigationControllerTests.m 3 | // RTRootNavigationControllerTests 4 | // 5 | // Created by rickytan on 06/08/2016. 6 | // Copyright (c) 2016 rickytan. All rights reserved. 7 | // 8 | 9 | @import XCTest; 10 | 11 | @interface Tests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation Tests 16 | 17 | - (void)setUp 18 | { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | @end 30 | 31 | -------------------------------------------------------------------------------- /Example/Tests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "cocoapods", '~> 1.14.2' 6 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.6) 5 | rexml 6 | activesupport (7.1.1) 7 | base64 8 | bigdecimal 9 | concurrent-ruby (~> 1.0, >= 1.0.2) 10 | connection_pool (>= 2.2.5) 11 | drb 12 | i18n (>= 1.6, < 2) 13 | minitest (>= 5.1) 14 | mutex_m 15 | tzinfo (~> 2.0) 16 | addressable (2.8.5) 17 | public_suffix (>= 2.0.2, < 6.0) 18 | algoliasearch (1.27.5) 19 | httpclient (~> 2.8, >= 2.8.3) 20 | json (>= 1.5.1) 21 | atomos (0.1.3) 22 | base64 (0.1.1) 23 | bigdecimal (3.1.4) 24 | claide (1.1.0) 25 | cocoapods (1.14.2) 26 | addressable (~> 2.8) 27 | claide (>= 1.0.2, < 2.0) 28 | cocoapods-core (= 1.14.2) 29 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 30 | cocoapods-downloader (>= 2.0) 31 | cocoapods-plugins (>= 1.0.0, < 2.0) 32 | cocoapods-search (>= 1.0.0, < 2.0) 33 | cocoapods-trunk (>= 1.6.0, < 2.0) 34 | cocoapods-try (>= 1.1.0, < 2.0) 35 | colored2 (~> 3.1) 36 | escape (~> 0.0.4) 37 | fourflusher (>= 2.3.0, < 3.0) 38 | gh_inspector (~> 1.0) 39 | molinillo (~> 0.8.0) 40 | nap (~> 1.0) 41 | ruby-macho (>= 2.3.0, < 3.0) 42 | xcodeproj (>= 1.23.0, < 2.0) 43 | cocoapods-core (1.14.2) 44 | activesupport (>= 5.0, < 8) 45 | addressable (~> 2.8) 46 | algoliasearch (~> 1.0) 47 | concurrent-ruby (~> 1.1) 48 | fuzzy_match (~> 2.0.4) 49 | nap (~> 1.0) 50 | netrc (~> 0.11) 51 | public_suffix (~> 4.0) 52 | typhoeus (~> 1.0) 53 | cocoapods-deintegrate (1.0.5) 54 | cocoapods-downloader (2.0) 55 | cocoapods-plugins (1.0.0) 56 | nap 57 | cocoapods-search (1.0.1) 58 | cocoapods-trunk (1.6.0) 59 | nap (>= 0.8, < 2.0) 60 | netrc (~> 0.11) 61 | cocoapods-try (1.2.0) 62 | colored2 (3.1.2) 63 | concurrent-ruby (1.2.2) 64 | connection_pool (2.4.1) 65 | drb (2.1.1) 66 | ruby2_keywords 67 | escape (0.0.4) 68 | ethon (0.16.0) 69 | ffi (>= 1.15.0) 70 | ffi (1.16.3) 71 | fourflusher (2.3.1) 72 | fuzzy_match (2.0.4) 73 | gh_inspector (1.1.3) 74 | httpclient (2.8.3) 75 | i18n (1.14.1) 76 | concurrent-ruby (~> 1.0) 77 | json (2.6.3) 78 | minitest (5.20.0) 79 | molinillo (0.8.0) 80 | mutex_m (0.1.2) 81 | nanaimo (0.3.0) 82 | nap (1.1.0) 83 | netrc (0.11.0) 84 | public_suffix (4.0.7) 85 | rexml (3.2.6) 86 | ruby-macho (2.5.1) 87 | ruby2_keywords (0.0.5) 88 | typhoeus (1.4.0) 89 | ethon (>= 0.9.0) 90 | tzinfo (2.0.6) 91 | concurrent-ruby (~> 1.0) 92 | xcodeproj (1.23.0) 93 | CFPropertyList (>= 2.3.3, < 4.0) 94 | atomos (~> 0.1.3) 95 | claide (>= 1.0.2, < 2.0) 96 | colored2 (~> 3.1) 97 | nanaimo (~> 0.3.0) 98 | rexml (~> 3.2.4) 99 | 100 | PLATFORMS 101 | x86_64-darwin-22 102 | 103 | DEPENDENCIES 104 | cocoapods (~> 1.14.2) 105 | 106 | BUNDLED WITH 107 | 2.4.10 108 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 rickytan 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RTRootNavigationController 2 | 3 | [![CI Status](http://img.shields.io/travis/rickytan/RTRootNavigationController.svg?style=flat)](https://travis-ci.org/rickytan/RTRootNavigationController) 4 | [![Version](https://img.shields.io/cocoapods/v/RTRootNavigationController.svg?style=flat)](http://cocoapods.org/pods/RTRootNavigationController) 5 | [![License](https://img.shields.io/cocoapods/l/RTRootNavigationController.svg?style=flat)](http://cocoapods.org/pods/RTRootNavigationController) 6 | [![Platform](https://img.shields.io/cocoapods/p/RTRootNavigationController.svg?style=flat)](http://cocoapods.org/pods/RTRootNavigationController) 7 | 8 | ## iOS 15 9 | Apple has changed some behavior of **UINavigationBar**([see](https://developer.apple.com/forums/thread/683265))on iOS 15, developers can override this on demands: 10 | 11 | iOS 15 上苹果改变了导航条的部分默认行为,开发者可以自己重写: 12 | 13 | ```objective-c 14 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 15 | { 16 | // setup appearance 17 | if (@available(iOS 15.0, *)) { 18 | [[UINavigationBar appearance] setScrollEdgeAppearance:({ 19 | UINavigationBarAppearance *app = [UINavigationBarAppearance new]; 20 | [app configureWithDefaultBackground]; 21 | // init app property 22 | // app.backgroundColor = xxx; 23 | // app.shadowColor = xxx; 24 | app; 25 | })]; 26 | } else { 27 | // Fallback on earlier versions 28 | } 29 | 30 | return YES; 31 | } 32 | ``` 33 | 34 | ## iPhone X 35 | How many lines of code should I write to fit in iPhone X? Zero. 36 | 37 | 我需要写多少代码来适配 **iPhone X**?0。 38 | 39 | ![iphone-x](https://user-images.githubusercontent.com/1250207/30429339-abb20914-9989-11e7-9058-c967839315f4.gif) 40 | 41 | ## Introduction 42 | More and more apps use custom navigation bar for each different view controller, instead of one common, global navigation bar. 43 | 44 | This project just help develops to solve this problem in a tricky way, develops use this navigation controller in a farmilar way just like you used to be, and you can have each view controller a individual navigation bar. 45 | 46 | 越来越多的应用为每一个 **VC** 设置单独的导航条,而不是之前那样使用一个全局统一的导航条,因为不同的 **VC** 有不同的视觉样式,前一个是蓝色的,后一个也许要做成红色、透明,或者干脆没有导航条。 47 | 48 | 虽然开发者可以在每个 **VC** 的 `- (void)viewWillAppear` (想想为什么不是 `- (void)viewDidLoad`) 方法中设置自己所需的样式,但是在同一个导航条上来回修改,稍不注意就会导致样式混乱。另一种实现方式,是隐藏全局那个导航条,每个 **VC** 自己通过 `addSubview:(UIView *)view` 的方式自己设置导航条。这种实现是可行的,但是使用不方便了,如: 49 | - 无法使用 `self.navigationItem.rightBarButtonItem` 等来设置导航按钮,而必须自己手动往 `navigationBar` 上加; 50 | - 无法使用 `self.title` 来修改导航标题,而必须自己添加监听; 51 | - 无法方便地设置 `navigationBarHidden`; 52 | - 无法方便地自动调整 `contentInsets`。 53 | 54 | 等等。 55 | 56 | 本项目提供一种透明的方式,让开发者像以前一样使用导航器,同时,每个 `push` 进来的 **VC** 有自己独立的导航条。 57 | 58 | ## Features 59 | 60 | * Custom navigation bar class support 61 | * Unwind support 62 | * Rotation support 63 | * Interactive pop enable and disable support 64 | * `Interface Builder` support 65 | 66 | * 每个 **VC** 支持自定义的 `navigationBarClass` 67 | * 支持 `unwind`(不知道什么是 `unwind`?请参考:[这里](https://developer.apple.com/library/ios/technotes/tn2298/_index.html)) 68 | * 支持转屏 69 | * 支持禁用交互式返回 70 | * 支持 `Interface Builder` 71 | 72 | ![screenshot](./ScreenShot/1.png) 73 | 74 | ![scrreecap](./ScreenShot/2.gif) 75 | 76 | ## Usage 77 | 78 | As an advise, please set `RTRootNavigationController` as your rootViewController: 79 | 80 | ```objective-c 81 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 82 | { 83 | 84 | UIViewController *yourController = ...; 85 | self.window.rootViewController = [[RTRootNavigationController alloc] initWithRootViewController:yourController]; 86 | return YES; 87 | } 88 | ``` 89 | 90 | you can implement following method to customize back bar button item (**Recommended**): 91 | 92 | ```objective-c 93 | - (UIBarButtonItem *)rt_customBackItemWithTarget:(id)target 94 | action:(SEL)action 95 | { 96 | return [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Back", nil) 97 | style:UIBarButtonItemStylePlain 98 | target:target 99 | action:action]; 100 | } 101 | ``` 102 | 103 | or just set `useSystemBackBarButtonItem` to **YES** and use the default one. 104 | 105 | To run the example project, clone the repo, and run `pod install` from the Example directory first. 106 | 107 | ## __Notice__(Only for below v0.6) 108 | 109 | Your **ViewController** hierarchy will change to: 110 | ``` 111 | RTRootNavigationController 112 | `- RTContainerViewController 113 | | `- RTContainerNavigationController 114 | | `- YourViewController1 115 | `- RTContainerViewController 116 | `- RTContainerNavigationController 117 | `- YourViewController2 118 | ``` 119 | So, if you access `self.navigationController` it returns a container navigation controller, and its `viewControllers` will always be **1**, i.e. `self`. Instead, your have to use `self.rt_navigationController.rt_viewController` to get all siblings, as metioned **[Here](https://github.com/rickytan/RTRootNavigationController/blob/master/RTRootNavigationController/Classes/UIViewController%2BRTRootNavigationController.h#L36)** and **[Here](https://github.com/rickytan/RTRootNavigationController/blob/master/RTRootNavigationController/Classes/RTRootNavigationController.h#L81)**. 120 | 121 | ## Requirements 122 | 123 | * **iOS 7** and up 124 | * **Xcode 7** and up 125 | 126 | ## Installation 127 | 128 | RTRootNavigationController is available through [CocoaPods](http://cocoapods.org). To install 129 | it, simply add the following line to your Podfile: 130 | 131 | ```ruby 132 | pod "RTRootNavigationController" 133 | ``` 134 | 135 | ## Author 136 | 137 | rickytan, ricky.tan.xin@gmail.com 138 | 139 | ## Alternatives 140 | 141 | - [**JTNavigationController**](https://github.com/JNTian/JTNavigationController) 142 | - 支持全屏返回 143 | - [**FDFullscreenPopGesture**](https://github.com/forkingdog/FDFullscreenPopGesture) 144 | - 使用原生的 *UINavigationController*,在 `- (void)viewWillAppear` 中做处理 145 | - 支持全屏返回 146 | 147 | ## Apps Integrated 148 | 149 | * [网易美学](https://itunes.apple.com/cn/app/%E7%BD%91%E6%98%93%E7%BE%8E%E5%AD%A6-%E9%A2%9C%E5%80%BC%E6%9C%80%E9%AB%98%E7%9A%84%E7%BE%8E%E5%A6%86%E7%A4%BE%E5%8C%BA/id1147533466?mt=8) 150 | 151 | ## License 152 | 153 | RTRootNavigationController is available under the MIT license. See the LICENSE file for more info. 154 | -------------------------------------------------------------------------------- /RTRootNavigationController.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint RTRootNavigationController.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'RTRootNavigationController' 11 | s.version = `git describe --abbrev=0`.strip 12 | s.summary = 'Transparently make every view controller has its own navigation bar' 13 | s.description = <<-DESC 14 | More and more apps use custom navigation bar for each different view controller, instead of one common, gloabal navigation bar. 15 | 16 | This project just help develops to solve this problem in a tricky way, develops use this navigation controller in a farmilar way just like you used to be, and 17 | you can have each view controller a individual navigation bar. 18 | DESC 19 | 20 | s.homepage = 'https://github.com/rickytan/RTRootNavigationController' 21 | s.screenshots = 'https://raw.githubusercontent.com/rickytan/RTRootNavigationController/master/ScreenShot/1.png', 'https://raw.githubusercontent.com/rickytan/RTRootNavigationController/master/ScreenShot/2.gif' 22 | s.license = { :type => 'MIT', :file => 'LICENSE' } 23 | s.author = { 'rickytan' => 'ricky.tan.xin@gmail.com' } 24 | s.source = { :git => 'https://github.com/rickytan/RTRootNavigationController.git', :tag => s.version.to_s } 25 | # s.social_media_url = 'https://twitter.com/' 26 | 27 | s.ios.deployment_target = '11.0' 28 | 29 | s.default_subspec = 'Core' 30 | 31 | s.subspec 'Core' do |core| 32 | core.source_files = 'RTRootNavigationController/Classes/**/*' 33 | end 34 | 35 | s.subspec 'Push' do |push| 36 | push.dependency 'RTRootNavigationController/Core' 37 | push.dependency 'RTInteractivePush', '~> 0.1.6' 38 | push.xcconfig = { 39 | 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) RT_INTERACTIVE_PUSH=1' 40 | } 41 | end 42 | 43 | # s.resource_bundles = { 44 | # 'RTRootNavigationController' => ['RTRootNavigationController/Assets/*.png'] 45 | # } 46 | 47 | # s.public_header_files = 'Pod/Classes/**/*.h' 48 | s.frameworks = 'UIKit', 'Foundation' 49 | # s.dependency 'AFNetworking', '~> 2.3' 50 | end 51 | -------------------------------------------------------------------------------- /RTRootNavigationController/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickytan/RTRootNavigationController/2ab3cf2ea416c409898a02d869697a9010bb5971/RTRootNavigationController/Assets/.gitkeep -------------------------------------------------------------------------------- /RTRootNavigationController/Classes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickytan/RTRootNavigationController/2ab3cf2ea416c409898a02d869697a9010bb5971/RTRootNavigationController/Classes/.gitkeep -------------------------------------------------------------------------------- /RTRootNavigationController/Classes/RTRootNavigationController.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 rickytan 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | 22 | #import 23 | #if RT_INTERACTIVE_PUSH 24 | #import 25 | #endif 26 | 27 | #import "UIViewController+RTRootNavigationController.h" 28 | #import "RTViewControllerAnimatedTransitioning.h" 29 | 30 | 31 | @interface RTContainerController : UIViewController 32 | @property (nonatomic, readonly, strong) __kindof UIViewController *contentViewController; 33 | @end 34 | 35 | 36 | /** 37 | * @class RTContainerNavigationController 38 | * @brief This Controller will forward all @a Navigation actions to its containing navigation controller, i.e. @b RTRootNavigationController. 39 | * If you are using UITabBarController in your project, it's recommand to wrap it in @b RTRootNavigationController as follows: 40 | * @code 41 | tabController.viewControllers = @[[[RTContainerNavigationController alloc] initWithRootViewController:vc1], 42 | [[RTContainerNavigationController alloc] initWithRootViewController:vc2], 43 | [[RTContainerNavigationController alloc] initWithRootViewController:vc3], 44 | [[RTContainerNavigationController alloc] initWithRootViewController:vc4]]; 45 | self.window.rootViewController = [[RTRootNavigationController alloc] initWithRootViewControllerNoWrapping:tabController]; 46 | * @endcode 47 | */ 48 | @interface RTContainerNavigationController : UINavigationController 49 | @end 50 | 51 | 52 | 53 | /*! 54 | * @class RTRootNavigationController 55 | * @superclass UINavigationController 56 | * @coclass RTContainerController 57 | * @coclass RTContainerNavigationController 58 | */ 59 | IB_DESIGNABLE 60 | @interface RTRootNavigationController : UINavigationController 61 | 62 | /*! 63 | * @brief use system original back bar item or custom back bar item returned by 64 | * @c -(UIBarButtonItem*)customBackItemWithTarget:action: , default is NO 65 | * @warning Set this to @b YES will @b INCREASE memory usage! 66 | */ 67 | @property (nonatomic, assign) IBInspectable BOOL useSystemBackBarButtonItem; 68 | 69 | /// Weather each individual navigation bar uses the visual style of root navigation bar. Default is @b NO 70 | @property (nonatomic, assign) IBInspectable BOOL transferNavigationBarAttributes; 71 | 72 | /*! 73 | * @brief use this property instead of @c visibleViewController to get the current visiable content view controller 74 | */ 75 | @property (nonatomic, readonly, strong) UIViewController *rt_visibleViewController; 76 | 77 | /*! 78 | * @brief use this property instead of @c topViewController to get the content view controller on the stack top 79 | */ 80 | @property (nonatomic, readonly, strong) UIViewController *rt_topViewController; 81 | 82 | /*! 83 | * @brief use this property to get all the content view controllers; 84 | */ 85 | @property (nonatomic, readonly, strong) NSArray <__kindof UIViewController *> *rt_viewControllers; 86 | 87 | /** 88 | * Init with a root view controller without wrapping into a navigation controller 89 | * 90 | * @param rootViewController The root view controller 91 | * 92 | * @return new instance 93 | */ 94 | - (instancetype)initWithRootViewControllerNoWrapping:(UIViewController *)rootViewController; 95 | 96 | /*! 97 | * @brief Remove a content view controller from the stack 98 | * 99 | * @param controller the content view controller 100 | */ 101 | - (void)removeViewController:(UIViewController *)controller NS_REQUIRES_SUPER; 102 | - (void)removeViewController:(UIViewController *)controller animated:(BOOL)flag NS_REQUIRES_SUPER; 103 | 104 | /*! 105 | * @brief Push a view controller and do sth. when animation is done 106 | * 107 | * @param viewController new view controller 108 | * @param animated use animation or not 109 | * @param block animation complete callback block 110 | */ 111 | - (void)pushViewController:(UIViewController *)viewController 112 | animated:(BOOL)animated 113 | complete:(void(^)(BOOL finished))block; 114 | 115 | /*! 116 | * @brief Pop current view controller on top with a complete handler 117 | * 118 | * @param animated use animation or not 119 | * @param block complete handler 120 | * 121 | * @return The current UIViewControllers(content controller) poped from the stack 122 | */ 123 | - (UIViewController *)popViewControllerAnimated:(BOOL)animated complete:(void(^)(BOOL finished))block; 124 | 125 | /*! 126 | * @brief Pop to a specific view controller with a complete handler 127 | * 128 | * @param viewController The view controller to pop to 129 | * @param animated use animation or not 130 | * @param block complete handler 131 | * 132 | * @return A array of UIViewControllers(content controller) poped from the stack 133 | */ 134 | - (NSArray <__kindof UIViewController *> *)popToViewController:(UIViewController *)viewController 135 | animated:(BOOL)animated 136 | complete:(void(^)(BOOL finished))block; 137 | 138 | /*! 139 | * @brief Pop to root view controller with a complete handler 140 | * 141 | * @param animated use animation or not 142 | * @param block complete handler 143 | * 144 | * @return A array of UIViewControllers(content controller) poped from the stack 145 | */ 146 | - (NSArray <__kindof UIViewController *> *)popToRootViewControllerAnimated:(BOOL)animated 147 | complete:(void(^)(BOOL finished))block; 148 | @end 149 | -------------------------------------------------------------------------------- /RTRootNavigationController/Classes/RTRootNavigationController.m: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 rickytan 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | #import 22 | 23 | #import "RTRootNavigationController.h" 24 | 25 | #import "UIViewController+RTRootNavigationController.h" 26 | 27 | 28 | @interface NSArray (RTRootNavigationController) 29 | - (NSArray *)rt_map:(id(^)(ObjectType obj, NSUInteger index))block; 30 | - (BOOL)rt_any:(BOOL(^)(ObjectType obj))block; 31 | @end 32 | 33 | @implementation NSArray (RTRootNavigationController) 34 | 35 | - (NSArray *)rt_map:(id (^)(id obj, NSUInteger index))block 36 | { 37 | if (!block) { 38 | block = ^(id obj, NSUInteger index) { 39 | return obj; 40 | }; 41 | } 42 | 43 | NSMutableArray *array = [NSMutableArray arrayWithCapacity:self.count]; 44 | [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL * stop) { 45 | [array addObject:block(obj, idx)]; 46 | }]; 47 | return [NSArray arrayWithArray:array]; 48 | } 49 | 50 | - (BOOL)rt_any:(BOOL (^)(id))block 51 | { 52 | if (!block) 53 | return NO; 54 | 55 | __block BOOL result = NO; 56 | [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL * stop) { 57 | if (block(obj)) { 58 | result = YES; 59 | *stop = YES; 60 | } 61 | }]; 62 | return result; 63 | } 64 | 65 | @end 66 | 67 | 68 | @interface RTRootNavigationController () 69 | @property (nonatomic, weak) id rt_delegate; 70 | @property (nonatomic, copy) void(^animationBlock)(BOOL finished); 71 | 72 | - (void)_installsLeftBarButtonItemIfNeededForViewController:(UIViewController *)vc; 73 | @end 74 | 75 | 76 | @interface RTContainerController () 77 | @property (nonatomic, strong) __kindof UIViewController *contentViewController; 78 | @property (nonatomic, strong) UINavigationController *containerNavigationController; 79 | 80 | + (instancetype)containerControllerWithController:(UIViewController *)controller; 81 | + (instancetype)containerControllerWithController:(UIViewController *)controller 82 | navigationBarClass:(Class)navigationBarClass; 83 | + (instancetype)containerControllerWithController:(UIViewController *)controller 84 | navigationBarClass:(Class)navigationBarClass 85 | withPlaceholderController:(BOOL)yesOrNo; 86 | + (instancetype)containerControllerWithController:(UIViewController *)controller 87 | navigationBarClass:(Class)navigationBarClass 88 | withPlaceholderController:(BOOL)yesOrNo 89 | backBarButtonItem:(UIBarButtonItem *)backItem 90 | backTitle:(NSString *)backTitle; 91 | 92 | - (instancetype)initWithController:(UIViewController *)controller; 93 | - (instancetype)initWithController:(UIViewController *)controller navigationBarClass:(Class)navigationBarClass; 94 | 95 | @end 96 | 97 | 98 | static inline UIViewController *RTSafeUnwrapViewController(UIViewController *controller) { 99 | if ([controller isKindOfClass:[RTContainerController class]]) { 100 | return ((RTContainerController *)controller).contentViewController; 101 | } 102 | return controller; 103 | } 104 | 105 | __attribute((overloadable)) static inline UIViewController *RTSafeWrapViewController(UIViewController *controller, 106 | Class navigationBarClass, 107 | BOOL withPlaceholder, 108 | UIBarButtonItem *backItem, 109 | NSString *backTitle) { 110 | if (![controller isKindOfClass:[RTContainerController class]] && 111 | ![controller.parentViewController isKindOfClass:[RTContainerController class]]) { 112 | return [RTContainerController containerControllerWithController:controller 113 | navigationBarClass:navigationBarClass 114 | withPlaceholderController:withPlaceholder 115 | backBarButtonItem:backItem 116 | backTitle:backTitle]; 117 | } 118 | return controller; 119 | } 120 | 121 | __attribute((overloadable)) static inline UIViewController *RTSafeWrapViewController(UIViewController *controller, Class navigationBarClass, BOOL withPlaceholder) { 122 | if (![controller isKindOfClass:[RTContainerController class]] && 123 | ![controller.parentViewController isKindOfClass:[RTContainerController class]]) { 124 | return [RTContainerController containerControllerWithController:controller 125 | navigationBarClass:navigationBarClass 126 | withPlaceholderController:withPlaceholder]; 127 | } 128 | return controller; 129 | } 130 | 131 | __attribute((overloadable)) static inline UIViewController *RTSafeWrapViewController(UIViewController *controller, Class navigationBarClass) { 132 | return RTSafeWrapViewController(controller, navigationBarClass, NO); 133 | } 134 | 135 | 136 | @implementation RTContainerController 137 | 138 | + (instancetype)containerControllerWithController:(UIViewController *)controller 139 | { 140 | return [[self alloc] initWithController:controller]; 141 | } 142 | 143 | + (instancetype)containerControllerWithController:(UIViewController *)controller 144 | navigationBarClass:(Class)navigationBarClass 145 | { 146 | return [[self alloc] initWithController:controller 147 | navigationBarClass:navigationBarClass]; 148 | } 149 | 150 | + (instancetype)containerControllerWithController:(UIViewController *)controller 151 | navigationBarClass:(Class)navigationBarClass 152 | withPlaceholderController:(BOOL)yesOrNo 153 | { 154 | return [[self alloc] initWithController:controller 155 | navigationBarClass:navigationBarClass 156 | withPlaceholderController:yesOrNo]; 157 | } 158 | 159 | + (instancetype)containerControllerWithController:(UIViewController *)controller 160 | navigationBarClass:(Class)navigationBarClass 161 | withPlaceholderController:(BOOL)yesOrNo 162 | backBarButtonItem:(UIBarButtonItem *)backItem 163 | backTitle:(NSString *)backTitle 164 | { 165 | return [[self alloc] initWithController:controller 166 | navigationBarClass:navigationBarClass 167 | withPlaceholderController:yesOrNo 168 | backBarButtonItem:backItem 169 | backTitle:backTitle]; 170 | } 171 | 172 | - (instancetype)initWithController:(UIViewController *)controller 173 | navigationBarClass:(Class)navigationBarClass 174 | withPlaceholderController:(BOOL)yesOrNo 175 | backBarButtonItem:(UIBarButtonItem *)backItem 176 | backTitle:(NSString *)backTitle 177 | { 178 | self = [super init]; 179 | if (self) { 180 | // not work while push to a hideBottomBar view controller, give up 181 | /* 182 | self.edgesForExtendedLayout = UIRectEdgeAll; 183 | self.extendedLayoutIncludesOpaqueBars = YES; 184 | self.automaticallyAdjustsScrollViewInsets = NO; 185 | */ 186 | 187 | self.contentViewController = controller; 188 | self.containerNavigationController = [[RTContainerNavigationController alloc] initWithNavigationBarClass:navigationBarClass 189 | toolbarClass:nil]; 190 | if (yesOrNo) { 191 | UIViewController *vc = [UIViewController new]; 192 | vc.title = backTitle; 193 | vc.navigationItem.backBarButtonItem = backItem; 194 | self.containerNavigationController.viewControllers = @[vc, controller]; 195 | } 196 | else 197 | self.containerNavigationController.viewControllers = @[controller]; 198 | 199 | [self addChildViewController:self.containerNavigationController]; 200 | [self.containerNavigationController didMoveToParentViewController:self]; 201 | } 202 | return self; 203 | } 204 | 205 | - (instancetype)initWithController:(UIViewController *)controller 206 | navigationBarClass:(Class)navigationBarClass 207 | withPlaceholderController:(BOOL)yesOrNo 208 | { 209 | return [self initWithController:controller 210 | navigationBarClass:navigationBarClass 211 | withPlaceholderController:yesOrNo 212 | backBarButtonItem:nil 213 | backTitle:nil]; 214 | } 215 | 216 | - (instancetype)initWithController:(UIViewController *)controller 217 | navigationBarClass:(Class)navigationBarClass 218 | { 219 | return [self initWithController:controller 220 | navigationBarClass:navigationBarClass 221 | withPlaceholderController:NO]; 222 | } 223 | 224 | - (instancetype)initWithController:(UIViewController *)controller 225 | { 226 | return [self initWithController:controller navigationBarClass:nil]; 227 | } 228 | 229 | - (instancetype)initWithContentController:(UIViewController *)controller 230 | { 231 | self = [super init]; 232 | if (self) { 233 | self.contentViewController = controller; 234 | [self addChildViewController:self.contentViewController]; 235 | [self.contentViewController didMoveToParentViewController:self]; 236 | } 237 | return self; 238 | } 239 | 240 | - (NSString *)debugDescription 241 | { 242 | return [NSString stringWithFormat:@"<%@: %p contentViewController: %@>", self.class, self, self.contentViewController]; 243 | } 244 | 245 | - (void)viewDidLoad 246 | { 247 | [super viewDidLoad]; 248 | if (self.containerNavigationController) { 249 | self.containerNavigationController.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; 250 | [self.view addSubview:self.containerNavigationController.view]; 251 | 252 | // fix issue #16 https://github.com/rickytan/RTRootNavigationController/issues/16 253 | self.containerNavigationController.view.frame = self.view.bounds; 254 | } 255 | else { 256 | self.contentViewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 257 | self.contentViewController.view.frame = self.view.bounds; 258 | [self.view addSubview:self.contentViewController.view]; 259 | } 260 | } 261 | 262 | - (void)viewDidLayoutSubviews 263 | { 264 | [super viewDidLayoutSubviews]; 265 | 266 | // remove the following to fix issue #16 https://github.com/rickytan/RTRootNavigationController/issues/16 267 | // self.containerNavigationController.view.frame = self.view.bounds; 268 | } 269 | 270 | - (BOOL)becomeFirstResponder 271 | { 272 | return [self.contentViewController becomeFirstResponder]; 273 | } 274 | 275 | - (BOOL)canBecomeFirstResponder 276 | { 277 | return [self.contentViewController canBecomeFirstResponder]; 278 | } 279 | 280 | - (UIStatusBarStyle)preferredStatusBarStyle 281 | { 282 | return [self.contentViewController preferredStatusBarStyle]; 283 | } 284 | 285 | - (BOOL)prefersStatusBarHidden 286 | { 287 | return [self.contentViewController prefersStatusBarHidden]; 288 | } 289 | 290 | - (UIStatusBarAnimation)preferredStatusBarUpdateAnimation 291 | { 292 | return [self.contentViewController preferredStatusBarUpdateAnimation]; 293 | } 294 | 295 | #if __IPHONE_11_0 && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 296 | - (nullable UIViewController *)childViewControllerForScreenEdgesDeferringSystemGestures 297 | { 298 | return self.contentViewController; 299 | } 300 | 301 | - (UIRectEdge)preferredScreenEdgesDeferringSystemGestures 302 | { 303 | return [self.contentViewController preferredScreenEdgesDeferringSystemGestures]; 304 | } 305 | 306 | - (BOOL)prefersHomeIndicatorAutoHidden 307 | { 308 | return [self.contentViewController prefersHomeIndicatorAutoHidden]; 309 | } 310 | 311 | - (UIViewController *)childViewControllerForHomeIndicatorAutoHidden 312 | { 313 | return self.contentViewController; 314 | } 315 | #endif 316 | 317 | - (BOOL)shouldAutorotate 318 | { 319 | return self.contentViewController.shouldAutorotate; 320 | } 321 | 322 | - (UIInterfaceOrientationMask)supportedInterfaceOrientations 323 | { 324 | return self.contentViewController.supportedInterfaceOrientations; 325 | } 326 | 327 | - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation 328 | { 329 | return self.contentViewController.preferredInterfaceOrientationForPresentation; 330 | } 331 | 332 | - (BOOL)hidesBottomBarWhenPushed 333 | { 334 | return self.contentViewController.hidesBottomBarWhenPushed; 335 | } 336 | 337 | - (NSString *)title 338 | { 339 | return self.contentViewController.title; 340 | } 341 | 342 | - (UITabBarItem *)tabBarItem 343 | { 344 | return self.contentViewController.tabBarItem; 345 | } 346 | 347 | - (id)rt_animatedTransitioning 348 | { 349 | return self.contentViewController.rt_animatedTransitioning; 350 | } 351 | 352 | #if RT_INTERACTIVE_PUSH 353 | - (nullable __kindof UIViewController *)rt_nextSiblingController 354 | { 355 | return self.contentViewController.rt_nextSiblingController; 356 | } 357 | #endif 358 | 359 | @end 360 | 361 | @interface UIViewController (RTContainerNavigationController) 362 | @property (nonatomic, assign, readonly) BOOL rt_hasSetInteractivePop; 363 | @end 364 | 365 | @implementation UIViewController (RTContainerNavigationController) 366 | 367 | - (BOOL)rt_hasSetInteractivePop 368 | { 369 | return !!objc_getAssociatedObject(self, @selector(rt_disableInteractivePop)); 370 | } 371 | 372 | @end 373 | 374 | 375 | @implementation RTContainerNavigationController 376 | 377 | - (instancetype)initWithRootViewController:(UIViewController *)rootViewController 378 | { 379 | self = [super initWithNavigationBarClass:rootViewController.rt_navigationBarClass 380 | toolbarClass:nil]; 381 | if (self) { 382 | [self pushViewController:rootViewController animated:NO]; 383 | // use following way will cause bug 384 | // self.viewControllers = @[rootViewController]; 385 | } 386 | return self; 387 | } 388 | 389 | - (void)viewDidLoad 390 | { 391 | [super viewDidLoad]; 392 | 393 | //self.interactivePopGestureRecognizer.delegate = nil; 394 | self.interactivePopGestureRecognizer.enabled = NO; 395 | 396 | if (self.rt_navigationController.transferNavigationBarAttributes) { 397 | #define BAR_PROPERTY(PROPERTY) self.navigationBar.PROPERTY = self.navigationController.navigationBar.PROPERTY 398 | 399 | BAR_PROPERTY(translucent); 400 | BAR_PROPERTY(tintColor); 401 | BAR_PROPERTY(barTintColor); 402 | BAR_PROPERTY(barStyle); 403 | BAR_PROPERTY(backgroundColor); 404 | 405 | [self.navigationBar setBackgroundImage:[self.navigationController.navigationBar backgroundImageForBarMetrics:UIBarMetricsDefault] 406 | forBarMetrics:UIBarMetricsDefault]; 407 | [self.navigationBar setTitleVerticalPositionAdjustment:[self.navigationController.navigationBar titleVerticalPositionAdjustmentForBarMetrics:UIBarMetricsDefault] 408 | forBarMetrics:UIBarMetricsDefault]; 409 | 410 | BAR_PROPERTY(titleTextAttributes); 411 | BAR_PROPERTY(shadowImage); 412 | BAR_PROPERTY(backIndicatorImage); 413 | BAR_PROPERTY(backIndicatorTransitionMaskImage); 414 | 415 | if (@available(iOS 11.0, *)) { 416 | BAR_PROPERTY(prefersLargeTitles); 417 | BAR_PROPERTY(largeTitleTextAttributes); 418 | } 419 | 420 | if (@available(iOS 13.0, *)) { 421 | BAR_PROPERTY(standardAppearance); 422 | BAR_PROPERTY(scrollEdgeAppearance); 423 | BAR_PROPERTY(compactAppearance); 424 | } 425 | 426 | if (@available(iOS 15.0, *)) { 427 | BAR_PROPERTY(compactScrollEdgeAppearance); 428 | } 429 | 430 | if (@available(iOS 16.0, *)) { 431 | BAR_PROPERTY(preferredBehavioralStyle); 432 | } 433 | 434 | #undef BAR_PROPERTY 435 | } 436 | } 437 | 438 | - (void)viewDidLayoutSubviews 439 | { 440 | [super viewDidLayoutSubviews]; 441 | 442 | UIViewController *viewController = self.topViewController; 443 | if (!viewController.rt_hasSetInteractivePop) { 444 | BOOL hasSetLeftItem = viewController.navigationItem.leftBarButtonItem != nil; 445 | if (self.navigationBarHidden) { 446 | viewController.rt_disableInteractivePop = YES; 447 | } else if (hasSetLeftItem) { 448 | viewController.rt_disableInteractivePop = YES; 449 | } else { 450 | viewController.rt_disableInteractivePop = NO; 451 | } 452 | 453 | } 454 | if ([self.parentViewController isKindOfClass:[RTContainerController class]] && 455 | [self.parentViewController.parentViewController isKindOfClass:[RTRootNavigationController class]]) { 456 | [self.rt_navigationController _installsLeftBarButtonItemIfNeededForViewController:viewController]; 457 | } 458 | } 459 | 460 | - (UITabBarController *)tabBarController 461 | { 462 | UITabBarController *tabController = [super tabBarController]; 463 | RTRootNavigationController *navigationController = self.rt_navigationController; 464 | if (tabController) { 465 | if (navigationController.tabBarController != tabController) { // Tab is child of Root VC 466 | return tabController; 467 | } 468 | else { 469 | return !tabController.tabBar.isTranslucent || [navigationController.rt_viewControllers rt_any:^BOOL(__kindof UIViewController *obj) { 470 | return obj.hidesBottomBarWhenPushed; 471 | }] ? nil : tabController; 472 | } 473 | } 474 | return nil; 475 | } 476 | 477 | - (NSArray *)viewControllers 478 | { 479 | if (self.navigationController) { 480 | if ([self.navigationController isKindOfClass:[RTRootNavigationController class]]) { 481 | return self.rt_navigationController.rt_viewControllers; 482 | } 483 | } 484 | return [super viewControllers]; 485 | } 486 | 487 | - (NSArray *)allowedChildViewControllersForUnwindingFromSource:(UIStoryboardUnwindSegueSource *)source 488 | { 489 | if (self.navigationController) { 490 | return [self.navigationController allowedChildViewControllersForUnwindingFromSource:source]; 491 | } 492 | return [super allowedChildViewControllersForUnwindingFromSource:source]; 493 | } 494 | 495 | - (void)pushViewController:(UIViewController *)viewController 496 | animated:(BOOL)animated 497 | { 498 | if (self.navigationController) { 499 | [self.navigationController pushViewController:viewController 500 | animated:animated]; 501 | } 502 | else { 503 | [super pushViewController:viewController 504 | animated:animated]; 505 | } 506 | } 507 | 508 | - (id)forwardingTargetForSelector:(SEL)aSelector 509 | { 510 | if ([self.navigationController respondsToSelector:aSelector]) 511 | return self.navigationController; 512 | return nil; 513 | } 514 | 515 | - (UIViewController *)popViewControllerAnimated:(BOOL)animated 516 | { 517 | if (self.navigationController) 518 | return [self.navigationController popViewControllerAnimated:animated]; 519 | return [super popViewControllerAnimated:animated]; 520 | } 521 | 522 | - (NSArray<__kindof UIViewController *> *)popToRootViewControllerAnimated:(BOOL)animated 523 | { 524 | if (self.navigationController) 525 | return [self.navigationController popToRootViewControllerAnimated:animated]; 526 | return [super popToRootViewControllerAnimated:animated]; 527 | } 528 | 529 | - (NSArray<__kindof UIViewController *> *)popToViewController:(UIViewController *)viewController 530 | animated:(BOOL)animated 531 | { 532 | if (self.navigationController) 533 | return [self.navigationController popToViewController:viewController 534 | animated:animated]; 535 | return [super popToViewController:viewController 536 | animated:animated]; 537 | } 538 | 539 | - (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated 540 | { 541 | if (self.navigationController) 542 | [self.navigationController setViewControllers:viewControllers 543 | animated:animated]; 544 | else 545 | [super setViewControllers:viewControllers animated:animated]; 546 | } 547 | 548 | - (void)setDelegate:(id)delegate 549 | { 550 | if (self.navigationController) 551 | self.navigationController.delegate = delegate; 552 | else 553 | [super setDelegate:delegate]; 554 | } 555 | 556 | - (void)setNavigationBarHidden:(BOOL)hidden animated:(BOOL)animated 557 | { 558 | [super setNavigationBarHidden:hidden animated:animated]; 559 | if (!self.visibleViewController.rt_hasSetInteractivePop) { 560 | self.visibleViewController.rt_disableInteractivePop = hidden; 561 | } 562 | } 563 | 564 | - (UIStatusBarStyle)preferredStatusBarStyle 565 | { 566 | return [self.topViewController preferredStatusBarStyle]; 567 | } 568 | 569 | - (BOOL)prefersStatusBarHidden 570 | { 571 | return [self.topViewController prefersStatusBarHidden]; 572 | } 573 | 574 | - (UIStatusBarAnimation)preferredStatusBarUpdateAnimation 575 | { 576 | return [self.topViewController preferredStatusBarUpdateAnimation]; 577 | } 578 | 579 | #if __IPHONE_11_0 && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 580 | - (nullable UIViewController *)childViewControllerForScreenEdgesDeferringSystemGestures 581 | { 582 | return self.topViewController; 583 | } 584 | 585 | - (UIRectEdge)preferredScreenEdgesDeferringSystemGestures 586 | { 587 | return [self.topViewController preferredScreenEdgesDeferringSystemGestures]; 588 | } 589 | 590 | - (BOOL)prefersHomeIndicatorAutoHidden 591 | { 592 | return [self.topViewController prefersHomeIndicatorAutoHidden]; 593 | } 594 | 595 | - (UIViewController *)childViewControllerForHomeIndicatorAutoHidden 596 | { 597 | return self.topViewController; 598 | } 599 | #endif 600 | 601 | @end 602 | 603 | 604 | @implementation RTRootNavigationController 605 | 606 | #pragma mark - Methods 607 | 608 | - (void)onBack:(id)sender 609 | { 610 | [self popViewControllerAnimated:YES]; 611 | } 612 | 613 | - (void)_commonInit 614 | { 615 | 616 | } 617 | 618 | - (void)_installsLeftBarButtonItemIfNeededForViewController:(UIViewController *)viewController 619 | { 620 | BOOL isRootVC = viewController == RTSafeUnwrapViewController(self.viewControllers.firstObject); 621 | BOOL hasSetLeftItem = viewController.navigationItem.leftBarButtonItem != nil; 622 | if (!isRootVC && !self.useSystemBackBarButtonItem && !hasSetLeftItem) { 623 | if ([viewController respondsToSelector:@selector(rt_customBackItemWithTarget:action:)]) { 624 | viewController.navigationItem.leftBarButtonItem = [viewController rt_customBackItemWithTarget:self 625 | action:@selector(onBack:)]; 626 | } 627 | else if ([viewController respondsToSelector:@selector(customBackItemWithTarget:action:)]) { 628 | #pragma clang diagnostic push 629 | #pragma clang diagnostic ignored "-Wdeprecated-declarations" 630 | viewController.navigationItem.leftBarButtonItem = [viewController customBackItemWithTarget:self 631 | action:@selector(onBack:)]; 632 | #pragma clang diagnostic pop 633 | } 634 | else { 635 | viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Back", nil) 636 | style:UIBarButtonItemStylePlain 637 | target:self 638 | action:@selector(onBack:)]; 639 | } 640 | } 641 | } 642 | 643 | #pragma mark - Overrides 644 | 645 | - (void)awakeFromNib 646 | { 647 | [super awakeFromNib]; 648 | self.viewControllers = [super viewControllers]; 649 | } 650 | 651 | - (instancetype)initWithCoder:(NSCoder *)aDecoder 652 | { 653 | self = [super initWithCoder:aDecoder]; 654 | if (self) { 655 | [self _commonInit]; 656 | } 657 | return self; 658 | } 659 | 660 | - (instancetype)initWithNavigationBarClass:(Class)navigationBarClass 661 | toolbarClass:(Class)toolbarClass 662 | { 663 | self = [super initWithNavigationBarClass:navigationBarClass toolbarClass:toolbarClass]; 664 | if (self) { 665 | [self _commonInit]; 666 | } 667 | return self; 668 | } 669 | 670 | - (instancetype)initWithRootViewController:(UIViewController *)rootViewController 671 | { 672 | self = [super initWithRootViewController:RTSafeWrapViewController(rootViewController, rootViewController.rt_navigationBarClass)]; 673 | if (self) { 674 | [self _commonInit]; 675 | } 676 | return self; 677 | } 678 | 679 | - (instancetype)initWithRootViewControllerNoWrapping:(UIViewController *)rootViewController 680 | { 681 | self = [super initWithRootViewController:[[RTContainerController alloc] initWithContentController:rootViewController]]; 682 | if (self) { 683 | // [super pushViewController:rootViewController 684 | // animated:NO]; 685 | [self _commonInit]; 686 | } 687 | return self; 688 | } 689 | 690 | - (void)viewDidLoad 691 | { 692 | [super viewDidLoad]; 693 | self.view.backgroundColor = [UIColor whiteColor]; 694 | 695 | [super setDelegate:self]; 696 | [super setNavigationBarHidden:YES 697 | animated:NO]; 698 | } 699 | 700 | - (void)setNavigationBarHidden:(__unused BOOL)hidden 701 | animated:(__unused BOOL)animated 702 | { 703 | // Override to protect 704 | } 705 | 706 | - (void)pushViewController:(UIViewController *)viewController 707 | animated:(BOOL)animated 708 | { 709 | if (viewController == nil) { 710 | if (self.animationBlock) { 711 | self.animationBlock(YES); 712 | self.animationBlock = nil; 713 | } 714 | return; 715 | } 716 | 717 | if (self.viewControllers.count > 0) { 718 | UIViewController *currentLast = RTSafeUnwrapViewController(self.viewControllers.lastObject); 719 | [super pushViewController:RTSafeWrapViewController(viewController, 720 | viewController.rt_navigationBarClass, 721 | self.useSystemBackBarButtonItem, 722 | currentLast.navigationItem.backBarButtonItem, 723 | currentLast.navigationItem.title ?: currentLast.title) 724 | animated:animated]; 725 | } 726 | else { 727 | [super pushViewController:RTSafeWrapViewController(viewController, viewController.rt_navigationBarClass) 728 | animated:animated]; 729 | } 730 | } 731 | 732 | - (UIViewController *)popViewControllerAnimated:(BOOL)animated 733 | { 734 | return RTSafeUnwrapViewController([super popViewControllerAnimated:animated]); 735 | } 736 | 737 | - (NSArray<__kindof UIViewController *> *)popToRootViewControllerAnimated:(BOOL)animated 738 | { 739 | return [[super popToRootViewControllerAnimated:animated] rt_map:^id(__kindof UIViewController *obj, NSUInteger index) { 740 | return RTSafeUnwrapViewController(obj); 741 | }]; 742 | } 743 | 744 | - (NSArray<__kindof UIViewController *> *)popToViewController:(UIViewController *)viewController 745 | animated:(BOOL)animated 746 | { 747 | __block UIViewController *controllerToPop = nil; 748 | [[super viewControllers] enumerateObjectsUsingBlock:^(__kindof UIViewController * obj, NSUInteger idx, BOOL * stop) { 749 | if (RTSafeUnwrapViewController(obj) == viewController) { 750 | controllerToPop = obj; 751 | *stop = YES; 752 | } 753 | }]; 754 | if (controllerToPop) { 755 | return [[super popToViewController:controllerToPop 756 | animated:animated] rt_map:^id(__kindof UIViewController * obj, __unused NSUInteger index) { 757 | return RTSafeUnwrapViewController(obj); 758 | }]; 759 | } 760 | return nil; 761 | } 762 | 763 | - (void)setViewControllers:(NSArray *)viewControllers 764 | animated:(BOOL)animated 765 | { 766 | [super setViewControllers:[viewControllers rt_map:^id(__kindof UIViewController * obj, NSUInteger index) { 767 | if (self.useSystemBackBarButtonItem && index > 0) { 768 | return RTSafeWrapViewController(obj, 769 | obj.rt_navigationBarClass, 770 | self.useSystemBackBarButtonItem, 771 | viewControllers[index - 1].navigationItem.backBarButtonItem, 772 | viewControllers[index - 1].title); 773 | } 774 | else 775 | return RTSafeWrapViewController(obj, obj.rt_navigationBarClass); 776 | }] 777 | animated:animated]; 778 | } 779 | 780 | - (void)setDelegate:(id)delegate 781 | { 782 | self.rt_delegate = delegate; 783 | } 784 | 785 | - (BOOL)shouldAutorotate 786 | { 787 | return self.topViewController.shouldAutorotate; 788 | } 789 | 790 | - (UIInterfaceOrientationMask)supportedInterfaceOrientations 791 | { 792 | return self.topViewController.supportedInterfaceOrientations; 793 | } 794 | 795 | - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation 796 | { 797 | return self.topViewController.preferredInterfaceOrientationForPresentation; 798 | } 799 | 800 | - (BOOL)respondsToSelector:(SEL)aSelector 801 | { 802 | if ([super respondsToSelector:aSelector]) { 803 | return YES; 804 | } 805 | return [self.rt_delegate respondsToSelector:aSelector]; 806 | } 807 | 808 | - (id)forwardingTargetForSelector:(SEL)aSelector 809 | { 810 | return self.rt_delegate; 811 | } 812 | 813 | #pragma mark - Public Methods 814 | 815 | - (UIViewController *)rt_topViewController 816 | { 817 | return RTSafeUnwrapViewController([super topViewController]); 818 | } 819 | 820 | - (UIViewController *)rt_visibleViewController 821 | { 822 | return RTSafeUnwrapViewController([super visibleViewController]); 823 | } 824 | 825 | - (NSArray <__kindof UIViewController *> *)rt_viewControllers 826 | { 827 | return [[super viewControllers] rt_map:^id(id obj, __unused NSUInteger index) { 828 | return RTSafeUnwrapViewController(obj); 829 | }]; 830 | } 831 | 832 | - (void)removeViewController:(UIViewController *)controller 833 | { 834 | [self removeViewController:controller animated:NO]; 835 | } 836 | 837 | - (void)removeViewController:(UIViewController *)controller animated:(BOOL)flag 838 | { 839 | NSMutableArray<__kindof UIViewController *> *controllers = [self.viewControllers mutableCopy]; 840 | __block UIViewController *controllerToRemove = nil; 841 | [controllers enumerateObjectsUsingBlock:^(__kindof UIViewController * obj, NSUInteger idx, BOOL * stop) { 842 | if (RTSafeUnwrapViewController(obj) == controller) { 843 | controllerToRemove = obj; 844 | *stop = YES; 845 | } 846 | }]; 847 | if (controllerToRemove) { 848 | [controllers removeObject:controllerToRemove]; 849 | [super setViewControllers:[NSArray arrayWithArray:controllers] animated:flag]; 850 | } 851 | } 852 | 853 | - (void)pushViewController:(UIViewController *)viewController 854 | animated:(BOOL)animated 855 | complete:(void (^)(BOOL))block 856 | { 857 | if (self.animationBlock) { 858 | self.animationBlock(NO); 859 | } 860 | self.animationBlock = block; 861 | [self pushViewController:viewController 862 | animated:animated]; 863 | } 864 | 865 | - (UIViewController *)popViewControllerAnimated:(BOOL)animated complete:(void (^)(BOOL))block 866 | { 867 | if (self.animationBlock) { 868 | self.animationBlock(NO); 869 | } 870 | self.animationBlock = block; 871 | 872 | UIViewController *vc = [self popViewControllerAnimated:animated]; 873 | if (!vc) { 874 | if (self.animationBlock) { 875 | self.animationBlock(YES); 876 | self.animationBlock = nil; 877 | } 878 | } 879 | return vc; 880 | } 881 | 882 | - (NSArray <__kindof UIViewController *> *)popToViewController:(UIViewController *)viewController 883 | animated:(BOOL)animated 884 | complete:(void (^)(BOOL))block 885 | { 886 | if (self.animationBlock) { 887 | self.animationBlock(NO); 888 | } 889 | self.animationBlock = block; 890 | NSArray <__kindof UIViewController *> *array = [self popToViewController:viewController 891 | animated:animated]; 892 | if (!array.count) { 893 | if (self.animationBlock) { 894 | self.animationBlock(YES); 895 | self.animationBlock = nil; 896 | } 897 | } 898 | return array; 899 | } 900 | 901 | - (NSArray <__kindof UIViewController *> *)popToRootViewControllerAnimated:(BOOL)animated 902 | complete:(void (^)(BOOL))block 903 | { 904 | if (self.animationBlock) { 905 | self.animationBlock(NO); 906 | } 907 | self.animationBlock = block; 908 | 909 | NSArray <__kindof UIViewController *> *array = [self popToRootViewControllerAnimated:animated]; 910 | if (!array.count) { 911 | if (self.animationBlock) { 912 | self.animationBlock(YES); 913 | self.animationBlock = nil; 914 | } 915 | } 916 | return array; 917 | } 918 | 919 | #pragma mark - UINavigationController Delegate 920 | 921 | - (void)navigationController:(UINavigationController *)navigationController 922 | willShowViewController:(UIViewController *)viewController 923 | animated:(BOOL)animated 924 | { 925 | BOOL isRootVC = viewController == navigationController.viewControllers.firstObject; 926 | viewController = RTSafeUnwrapViewController(viewController); 927 | if (!isRootVC && viewController.isViewLoaded) { 928 | 929 | BOOL hasSetLeftItem = viewController.navigationItem.leftBarButtonItem != nil; 930 | if (hasSetLeftItem && !viewController.rt_hasSetInteractivePop) { 931 | viewController.rt_disableInteractivePop = YES; 932 | } 933 | else if (!viewController.rt_hasSetInteractivePop) { 934 | viewController.rt_disableInteractivePop = NO; 935 | } 936 | // fix #292 https://github.com/rickytan/RTRootNavigationController/issues/292 937 | // 延迟到didShow里执行 938 | // [self _installsLeftBarButtonItemIfNeededForViewController:viewController]; 939 | } 940 | 941 | if ([self.rt_delegate respondsToSelector:@selector(navigationController:willShowViewController:animated:)]) { 942 | [self.rt_delegate navigationController:navigationController 943 | willShowViewController:viewController 944 | animated:animated]; 945 | } 946 | } 947 | 948 | - (void)navigationController:(UINavigationController *)navigationController 949 | didShowViewController:(UIViewController *)viewController 950 | animated:(BOOL)animated 951 | { 952 | BOOL isRootVC = viewController == navigationController.viewControllers.firstObject; 953 | viewController = RTSafeUnwrapViewController(viewController); 954 | 955 | // fix #292 https://github.com/rickytan/RTRootNavigationController/issues/292 956 | if (!isRootVC && viewController.isViewLoaded) { 957 | [self _installsLeftBarButtonItemIfNeededForViewController:viewController]; 958 | } 959 | 960 | // fix #258 https://github.com/rickytan/RTRootNavigationController/issues/258 961 | // animated 为 NO 时的时序不太对,手动触发 viewDidLoad 962 | if (!animated) { 963 | [viewController view]; 964 | } 965 | if (viewController.rt_disableInteractivePop) { 966 | self.interactivePopGestureRecognizer.delegate = nil; 967 | self.interactivePopGestureRecognizer.enabled = NO; 968 | } else { 969 | self.interactivePopGestureRecognizer.delegate = self; 970 | self.interactivePopGestureRecognizer.enabled = !isRootVC; 971 | } 972 | 973 | [RTRootNavigationController attemptRotationToDeviceOrientation]; 974 | 975 | 976 | if ([self.rt_delegate respondsToSelector:@selector(navigationController:didShowViewController:animated:)]) { 977 | [self.rt_delegate navigationController:navigationController 978 | didShowViewController:viewController 979 | animated:animated]; 980 | } 981 | 982 | if (self.animationBlock) { 983 | if (animated) { 984 | dispatch_async(dispatch_get_main_queue(), ^{ 985 | if (self.animationBlock) { 986 | self.animationBlock(YES); 987 | self.animationBlock = nil; 988 | } 989 | }); 990 | } 991 | else { 992 | self.animationBlock(YES); 993 | self.animationBlock = nil; 994 | } 995 | } 996 | } 997 | 998 | - (UIInterfaceOrientationMask)navigationControllerSupportedInterfaceOrientations:(UINavigationController *)navigationController 999 | { 1000 | 1001 | if ([self.rt_delegate respondsToSelector:@selector(navigationControllerSupportedInterfaceOrientations:)]) { 1002 | return [self.rt_delegate navigationControllerSupportedInterfaceOrientations:navigationController]; 1003 | } 1004 | return UIInterfaceOrientationMaskAll; 1005 | } 1006 | 1007 | - (UIInterfaceOrientation)navigationControllerPreferredInterfaceOrientationForPresentation:(UINavigationController *)navigationController 1008 | { 1009 | 1010 | if ([self.rt_delegate respondsToSelector:@selector(navigationControllerPreferredInterfaceOrientationForPresentation:)]) { 1011 | return [self.rt_delegate navigationControllerPreferredInterfaceOrientationForPresentation:navigationController]; 1012 | } 1013 | return UIInterfaceOrientationPortrait; 1014 | } 1015 | 1016 | - (id )navigationController:(UINavigationController *)navigationController 1017 | interactionControllerForAnimationController:(id ) animationController 1018 | { 1019 | if ([self.rt_delegate respondsToSelector:@selector(navigationController:interactionControllerForAnimationController:)]) { 1020 | return [self.rt_delegate navigationController:navigationController 1021 | interactionControllerForAnimationController:animationController]; 1022 | } 1023 | if ([animationController respondsToSelector:@selector(rt_interactiveTransitioning)]) { 1024 | return [((id )animationController) rt_interactiveTransitioning]; 1025 | } 1026 | return nil; 1027 | } 1028 | 1029 | - (id )navigationController:(UINavigationController *)navigationController 1030 | animationControllerForOperation:(UINavigationControllerOperation)operation 1031 | fromViewController:(UIViewController *)fromVC 1032 | toViewController:(UIViewController *)toVC 1033 | { 1034 | if (operation == UINavigationControllerOperationPush) { 1035 | self.interactivePopGestureRecognizer.delegate = nil; 1036 | self.interactivePopGestureRecognizer.enabled = NO; 1037 | } 1038 | if ([self.rt_delegate respondsToSelector:@selector(navigationController:animationControllerForOperation:fromViewController:toViewController:)]) { 1039 | return [self.rt_delegate navigationController:navigationController 1040 | animationControllerForOperation:operation 1041 | fromViewController:RTSafeUnwrapViewController(fromVC) 1042 | toViewController:RTSafeUnwrapViewController(toVC)]; 1043 | } 1044 | return operation == UINavigationControllerOperationPush ? [toVC rt_animatedTransitioning] : [fromVC rt_animatedTransitioning]; 1045 | } 1046 | 1047 | 1048 | 1049 | #pragma mark - UIGestureRecognizerDelegate 1050 | 1051 | - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 1052 | { 1053 | return (gestureRecognizer == self.interactivePopGestureRecognizer); 1054 | } 1055 | 1056 | - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer 1057 | shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { 1058 | return (gestureRecognizer == self.interactivePopGestureRecognizer); 1059 | } 1060 | 1061 | @end 1062 | -------------------------------------------------------------------------------- /RTRootNavigationController/Classes/RTViewControllerAnimatedTransitioning.h: -------------------------------------------------------------------------------- 1 | // 2 | // RTViewControllerAnimatedTransitioning.h 3 | // RTRootNavigationController 4 | // 5 | // Created by chenguixin on 2020/3/16. 6 | // 7 | 8 | #import 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @protocol RTViewControllerAnimatedTransitioning 13 | 14 | - (id)rt_interactiveTransitioning; 15 | 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /RTRootNavigationController/Classes/UIViewController+RTRootNavigationController.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 rickytan 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | #import 22 | 23 | @class RTRootNavigationController; 24 | 25 | @protocol RTNavigationItemCustomizable 26 | 27 | @optional 28 | 29 | /*! 30 | * @brief Override this method to provide a custom back bar item, default is a normal @c UIBarButtonItem with title @b "Back" 31 | * 32 | * @param target the action target 33 | * @param action the pop back action 34 | * 35 | * @return a custom UIBarButtonItem 36 | */ 37 | - (UIBarButtonItem *)customBackItemWithTarget:(id)target action:(SEL)action DEPRECATED_MSG_ATTRIBUTE("use rt_customBackItemWithTarget:action: instead!"); 38 | - (UIBarButtonItem *)rt_customBackItemWithTarget:(id)target action:(SEL)action; 39 | 40 | @end 41 | 42 | IB_DESIGNABLE 43 | @interface UIViewController (RTRootNavigationController) 44 | 45 | /*! 46 | * @brief set this property to @b YES to disable interactive pop 47 | */ 48 | @property (nonatomic, assign) IBInspectable BOOL rt_disableInteractivePop; 49 | 50 | /*! 51 | * @brief @c self\.navigationControlle will get a wrapping @c UINavigationController, use this property to get the real navigation controller 52 | */ 53 | @property (nonatomic, readonly, strong) RTRootNavigationController *rt_navigationController; 54 | 55 | /*! 56 | * @brief Override this method to provide a custom subclass of @c UINavigationBar, defaults return nil 57 | * 58 | * @return new UINavigationBar class 59 | */ 60 | - (Class)rt_navigationBarClass; 61 | 62 | 63 | @property (nonatomic, readonly) id rt_animatedTransitioning; 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /RTRootNavigationController/Classes/UIViewController+RTRootNavigationController.m: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 rickytan 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | #import 22 | 23 | #import "UIViewController+RTRootNavigationController.h" 24 | #import "RTRootNavigationController.h" 25 | 26 | @implementation UIViewController (RTRootNavigationController) 27 | @dynamic rt_disableInteractivePop; 28 | 29 | - (void)setRt_disableInteractivePop:(BOOL)rt_disableInteractivePop 30 | { 31 | objc_setAssociatedObject(self, @selector(rt_disableInteractivePop), @(rt_disableInteractivePop), OBJC_ASSOCIATION_RETAIN_NONATOMIC); 32 | 33 | if (self.rt_navigationController.rt_topViewController == self) { 34 | self.rt_navigationController.interactivePopGestureRecognizer.enabled = !rt_disableInteractivePop; 35 | } 36 | } 37 | 38 | - (BOOL)rt_disableInteractivePop 39 | { 40 | return [objc_getAssociatedObject(self, @selector(rt_disableInteractivePop)) boolValue]; 41 | } 42 | 43 | - (Class)rt_navigationBarClass 44 | { 45 | return nil; 46 | } 47 | 48 | - (RTRootNavigationController *)rt_navigationController 49 | { 50 | UIViewController *vc = self; 51 | while (vc && ![vc isKindOfClass:[RTRootNavigationController class]]) { 52 | vc = vc.navigationController; 53 | } 54 | return (RTRootNavigationController *)vc; 55 | } 56 | 57 | - (id)rt_animatedTransitioning 58 | { 59 | return nil; 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /ScreenShot/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickytan/RTRootNavigationController/2ab3cf2ea416c409898a02d869697a9010bb5971/ScreenShot/1.png -------------------------------------------------------------------------------- /ScreenShot/2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickytan/RTRootNavigationController/2ab3cf2ea416c409898a02d869697a9010bb5971/ScreenShot/2.gif -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj --------------------------------------------------------------------------------