├── EachNavigationBar ├── Assets │ ├── .gitkeep │ └── EachNavigationBar.xcassets │ │ ├── Contents.json │ │ └── navigation_back_default.imageset │ │ ├── navigation_back_default.png │ │ └── Contents.json └── Classes │ ├── .gitkeep │ ├── Const.swift │ ├── AssociatedKeys.swift │ ├── Navigation.swift │ ├── UIViewController+Navigation.swift │ ├── Shadow.swift │ ├── EachNavigationItem.swift │ ├── UITableViewController+EachNavigationBar.swift │ ├── UINavigationController+EachNavigationBar.swift │ ├── UINavigationBar+Sugar.swift │ ├── BackBarButtonItem.swift │ ├── UIViewController+Swizzling.swift │ ├── UIViewController+Associated.swift │ ├── Configuration.swift │ ├── UIViewController+EachNavigationBar.swift │ └── EachNavigationBar.swift ├── _Pods.xcodeproj ├── Gemfile ├── demo_new.gif ├── demo_push.gif ├── Example ├── EachNavigationBar │ ├── Images.xcassets │ │ ├── Contents.json │ │ ├── nav.imageset │ │ │ ├── top@2x.png │ │ │ ├── top@3x.png │ │ │ └── Contents.json │ │ ├── back.imageset │ │ │ ├── sk_common_back_gray@2x.png │ │ │ ├── sk_common_back_gray@2x-1.png │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── EachNavigationBar_Example-Bridging-Header.h │ ├── OCViewController.h │ ├── OCViewController.m │ ├── Info.plist │ ├── AppDelegate.swift │ ├── NextViewController.swift │ ├── MainViewController.swift │ ├── ViewController.swift │ ├── TableViewController.swift │ ├── Base.lproj │ │ └── LaunchScreen.xib │ └── MainViewController.xib ├── EachNavigationBar.xcworkspace │ ├── xcuserdata │ │ ├── lee.xcuserdatad │ │ │ ├── UserInterfaceState.xcuserstate │ │ │ └── xcdebugger │ │ │ │ └── Breakpoints_v2.xcbkptlist │ │ └── pircate.xcuserdatad │ │ │ ├── IDEFindNavigatorScopes.plist │ │ │ └── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── EachNavigationBar.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ ├── xcuserdata │ │ ├── lee.xcuserdatad │ │ │ └── xcschemes │ │ │ │ └── xcschememanagement.plist │ │ └── pircate.xcuserdatad │ │ │ └── xcschemes │ │ │ └── EachNavigationBar-Example.xcscheme │ └── project.pbxproj ├── Podfile ├── Podfile.lock └── Tests │ ├── Tests.swift │ └── Info.plist ├── .github └── workflows │ └── Lint.yml ├── .swiftlint.yml ├── EachNavigationBar.podspec ├── fastlane ├── README.md └── Fastfile ├── .gitignore ├── LICENSE ├── README_CN.md ├── README.md └── Gemfile.lock /EachNavigationBar/Assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /EachNavigationBar/Classes/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "fastlane" 4 | gem "cocoapods" -------------------------------------------------------------------------------- /demo_new.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pircate/EachNavigationBar/HEAD/demo_new.gif -------------------------------------------------------------------------------- /demo_push.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pircate/EachNavigationBar/HEAD/demo_push.gif -------------------------------------------------------------------------------- /Example/EachNavigationBar/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /EachNavigationBar/Assets/EachNavigationBar.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/EachNavigationBar/Images.xcassets/nav.imageset/top@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pircate/EachNavigationBar/HEAD/Example/EachNavigationBar/Images.xcassets/nav.imageset/top@2x.png -------------------------------------------------------------------------------- /Example/EachNavigationBar/Images.xcassets/nav.imageset/top@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pircate/EachNavigationBar/HEAD/Example/EachNavigationBar/Images.xcassets/nav.imageset/top@3x.png -------------------------------------------------------------------------------- /Example/EachNavigationBar/EachNavigationBar_Example-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | #import "OCViewController.h" 6 | -------------------------------------------------------------------------------- /Example/EachNavigationBar/Images.xcassets/back.imageset/sk_common_back_gray@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pircate/EachNavigationBar/HEAD/Example/EachNavigationBar/Images.xcassets/back.imageset/sk_common_back_gray@2x.png -------------------------------------------------------------------------------- /Example/EachNavigationBar/Images.xcassets/back.imageset/sk_common_back_gray@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pircate/EachNavigationBar/HEAD/Example/EachNavigationBar/Images.xcassets/back.imageset/sk_common_back_gray@2x-1.png -------------------------------------------------------------------------------- /Example/EachNavigationBar.xcworkspace/xcuserdata/lee.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pircate/EachNavigationBar/HEAD/Example/EachNavigationBar.xcworkspace/xcuserdata/lee.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Example/EachNavigationBar.xcworkspace/xcuserdata/lee.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /Example/EachNavigationBar.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /EachNavigationBar/Assets/EachNavigationBar.xcassets/navigation_back_default.imageset/navigation_back_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pircate/EachNavigationBar/HEAD/EachNavigationBar/Assets/EachNavigationBar.xcassets/navigation_back_default.imageset/navigation_back_default.png -------------------------------------------------------------------------------- /Example/EachNavigationBar.xcworkspace/xcuserdata/pircate.xcuserdatad/IDEFindNavigatorScopes.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Example/EachNavigationBar.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/EachNavigationBar.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '13.0' 2 | use_frameworks! 3 | install! 'cocoapods', 4 | :disable_input_output_paths => true, 5 | :share_schemes_for_development_pods => true 6 | 7 | target 'EachNavigationBar_Example' do 8 | pod 'EachNavigationBar', :path => '../' 9 | 10 | target 'EachNavigationBar_Tests' do 11 | inherit! :search_paths 12 | 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - EachNavigationBar (2.1.1) 3 | 4 | DEPENDENCIES: 5 | - EachNavigationBar (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | EachNavigationBar: 9 | :path: "../" 10 | 11 | SPEC CHECKSUMS: 12 | EachNavigationBar: 517a39b0d259687a3101a4a87e4964a5a94343bf 13 | 14 | PODFILE CHECKSUM: 86c6b2575c42ec1953b1a9e75aa636bf68bc59c9 15 | 16 | COCOAPODS: 1.13.0 17 | -------------------------------------------------------------------------------- /Example/EachNavigationBar/OCViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCViewController.h 3 | // EachNavigationBar_Example 4 | // 5 | // Created by Pircate(gao497868860@gmail.com) on 2018/10/25 6 | // Copyright © 2018 CocoaPods. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface OCViewController : UIViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /.github/workflows/Lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | test: 11 | 12 | runs-on: macOS-latest 13 | 14 | steps: 15 | - uses: actions/checkout@master 16 | - name: Install cocoapods 17 | run: gem install cocoapods --pre && pod install --project-directory=Example 18 | - name: Lib lint 19 | run: pod lib lint --allow-warnings 20 | -------------------------------------------------------------------------------- /Example/EachNavigationBar/Images.xcassets/nav.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "top@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "top@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Example/EachNavigationBar/OCViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // OCViewController.m 3 | // EachNavigationBar_Example 4 | // 5 | // Created by Pircate(gao497868860@gmail.com) on 2018/10/25 6 | // Copyright © 2018 CocoaPods. All rights reserved. 7 | // 8 | 9 | #import "OCViewController.h" 10 | @import EachNavigationBar; 11 | 12 | @interface OCViewController () 13 | 14 | @end 15 | 16 | @implementation OCViewController 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Example/Tests/Tests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import EachNavigationBar 3 | 4 | class Tests: XCTestCase { 5 | 6 | func testExample() { 7 | // This is an example of a functional test case. 8 | XCTAssert(true, "Pass") 9 | } 10 | 11 | func testPerformanceExample() { 12 | // This is an example of a performance test case. 13 | self.measure { 14 | // Put the code you want to measure the time of here. 15 | } 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /EachNavigationBar/Assets/EachNavigationBar.xcassets/navigation_back_default.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "filename" : "navigation_back_default.png", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/EachNavigationBar.xcodeproj/xcuserdata/lee.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | EachNavigationBar_Example.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 5 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Example/EachNavigationBar/Images.xcassets/back.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "sk_common_back_gray@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "sk_common_back_gray@2x-1.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /EachNavigationBar/Classes/Const.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Const.swift 3 | // EachNavigationBar 4 | // 5 | // Created by Pircate(gao497868860@gmail.com) on 2018/11/20 6 | // Copyright © 2018年 Pircate. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension CGFloat { 12 | 13 | static let navigationBarHeight: CGFloat = 44.0 14 | } 15 | 16 | extension UIEdgeInsets { 17 | 18 | static let barLayoutPaddings: UIEdgeInsets = .init(top: 0, left: 16, bottom: 0, right: 16) 19 | 20 | static let barLayoutMargins: UIEdgeInsets = .init(top: 8, left: 16, bottom: 8, right: 16) 21 | } 22 | -------------------------------------------------------------------------------- /EachNavigationBar/Classes/AssociatedKeys.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AssociatedKeys.swift 3 | // EachNavigationBar 4 | // 5 | // Created by Pircate(gao497868860@gmail.com) on 2018/8/6. 6 | // Copyright © 2018年 Pircate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct AssociatedKeys { 12 | 13 | static var configuration = "com.pircate.github.configuration" 14 | 15 | static var navigationBar = "com.pircate.github.navigationBar" 16 | 17 | static var navigationItem = "com.pircate.github.navigationItem" 18 | 19 | static var observation = "com.pircate.github.observation" 20 | } 21 | -------------------------------------------------------------------------------- /.swiftlint.yml: -------------------------------------------------------------------------------- 1 | --- 2 | included: 3 | excluded: 4 | - Carthage 5 | - Pods 6 | line_length: 7 | warning: 120 8 | ignores_function_declarations: true 9 | ignores_comments: true 10 | disabled_rules: 11 | - empty_enum_arguments 12 | - trailing_whitespace 13 | - cyclomatic_complexity 14 | - file_length 15 | - type_name 16 | - inclusive_language 17 | - function_parameter_count 18 | - identifier_name 19 | - type_body_length 20 | - function_body_length 21 | - nesting 22 | - unneeded_break_in_switch 23 | identifier_name: 24 | excluded: 25 | - i 26 | - idx 27 | - h 28 | - w 29 | - x 30 | - y 31 | - id 32 | - url 33 | - min 34 | - max 35 | - r 36 | - g 37 | - b 38 | - a 39 | -------------------------------------------------------------------------------- /EachNavigationBar/Classes/Navigation.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Navigation.swift 3 | // EachNavigationBar 4 | // 5 | // Created by Pircate(gao497868860@gmail.com) on 2018/6/26. 6 | // Copyright © 2018年 Pircate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public struct Navigation { 12 | 13 | let base: Base 14 | 15 | init(_ base: Base) { 16 | self.base = base 17 | } 18 | } 19 | 20 | public protocol NavigationCompatible { 21 | 22 | associatedtype CompatibleType 23 | 24 | var navigation: CompatibleType { get } 25 | } 26 | 27 | public extension NavigationCompatible { 28 | 29 | var navigation: Navigation { 30 | return Navigation(self) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Example/EachNavigationBar.xcworkspace/xcuserdata/pircate.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /EachNavigationBar.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'EachNavigationBar' 3 | s.version = '2.1.2' 4 | s.summary = 'A custom navigation bar of UIViewController.' 5 | s.homepage = 'https://github.com/Pircate/EachNavigationBar' 6 | s.license = { :type => 'MIT', :file => 'LICENSE' } 7 | s.author = { 'Pircate' => 'gao497868860@gmail.com' } 8 | s.source = { :git => 'https://github.com/Pircate/EachNavigationBar.git', :tag => s.version.to_s } 9 | s.source_files = 'EachNavigationBar/Classes/**/*' 10 | s.resource_bundles = { 'EachNavigationBar' => ['EachNavigationBar/Assets/*.xcassets'] } 11 | s.frameworks = 'UIKit' 12 | s.swift_versions = ['5.1', '5.2', '5.3'] 13 | s.ios.deployment_target = '13.0' 14 | end 15 | -------------------------------------------------------------------------------- /EachNavigationBar/Classes/UIViewController+Navigation.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+Navigation.swift 3 | // EachNavigationBar 4 | // 5 | // Created by Pircate(gao497868860@gmail.com) on 2018/6/26. 6 | // Copyright © 2018年 Pircate. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIViewController: NavigationCompatible {} 12 | 13 | public extension Navigation where Base: UIViewController { 14 | 15 | var bar: EachNavigationBar { 16 | return base._navigationBar 17 | } 18 | 19 | var item: UINavigationItem { 20 | return base._navigationItem 21 | } 22 | } 23 | 24 | public extension Navigation where Base: UINavigationController { 25 | 26 | var configuration: UINavigationController.Configuration { 27 | return base._configuration 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Example/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 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /fastlane/README.md: -------------------------------------------------------------------------------- 1 | fastlane documentation 2 | ---- 3 | 4 | # Installation 5 | 6 | Make sure you have the latest version of the Xcode command line tools installed: 7 | 8 | ```sh 9 | xcode-select --install 10 | ``` 11 | 12 | For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane) 13 | 14 | # Available Actions 15 | 16 | ## iOS 17 | 18 | ### ios release 19 | 20 | ```sh 21 | [bundle exec] fastlane ios release 22 | ``` 23 | 24 | release new version 25 | 26 | ---- 27 | 28 | This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run. 29 | 30 | More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools). 31 | 32 | The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools). 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX specific 2 | .DS_Store 3 | .AppleDouble 4 | .LSOverride 5 | Icon 6 | ._* 7 | .DocumentRevisions-V100 8 | .fseventsd 9 | .Spotlight-V100 10 | .TemporaryItems 11 | .Trashes 12 | .VolumeIcon.icns 13 | .AppleDB 14 | .AppleDesktop 15 | Network Trash Folder 16 | Temporary Items 17 | .apdisk 18 | 19 | # Xcode, Swift and Obj-C specific 20 | DerivedData 21 | *.pbxuser 22 | !default.pbxuser 23 | *.mode1v3 24 | !default.mode1v3 25 | *.mode2v3 26 | !default.mode2v3 27 | *.perspectivev3 28 | !default.perspectivev3 29 | xcuserdata 30 | *.xccheckout 31 | *.moved-aside 32 | *.xcuserstate 33 | *.xcscmblueprint 34 | *.hmap 35 | *.ipa 36 | 37 | # Cocoa Pods specific 38 | Pods/ 39 | *.xcworkspace 40 | #Podfile.lock 41 | 42 | .idea/* 43 | MiFit/DevLib/UI_HM_Lib/Theme/.idea/* 44 | Carthage/Checkouts/* 45 | xcschememanagement.plist 46 | SportDetail.xcworkspace/xcuserdata/huami.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist 47 | *.xcbkptlist 48 | report.xml 49 | -------------------------------------------------------------------------------- /fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | default_platform(:ios) 2 | 3 | platform :ios do 4 | 5 | desc "release new version" 6 | lane :release do |options| 7 | # 获取 podspec 文件路径 8 | podspec_json = read_podspec() 9 | podspec_path = "#{podspec_json["name"]}.podspec" 10 | 11 | target_version = options[:version] 12 | if !target_version.nil? 13 | # 设置 podspec 版本 14 | version_bump_podspec( 15 | path: podspec_path, 16 | version_number: target_version 17 | ) 18 | 19 | # 添加并提交 podspec 文件 20 | git_add(path: podspec_path) 21 | git_commit( 22 | path: podspec_path, 23 | message: "release #{target_version} version" 24 | ) 25 | 26 | # 推送 git 提交 27 | push_to_git_remote 28 | end 29 | 30 | # 获取版本号 31 | target_version = version_get_podspec(path: podspec_path) 32 | 33 | # 添加标签 34 | if !git_tag_exists(tag: target_version) 35 | add_git_tag tag: target_version 36 | end 37 | 38 | # 推送标签 39 | push_git_tags 40 | 41 | # 发布到 pod 42 | pod_push(path: podspec_path, allow_warnings: true) 43 | end 44 | end -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 Pircate 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 | -------------------------------------------------------------------------------- /Example/EachNavigationBar/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" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /EachNavigationBar/Classes/Shadow.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Shadow.swift 3 | // EachNavigationBar 4 | // 5 | // Created by Pircate(gao497868860@gmail.com) on 2019/2/27 6 | // Copyright © 2019年 Pircate. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public struct Shadow { 12 | let color: CGColor? 13 | let opacity: Float 14 | let offset: CGSize 15 | let radius: CGFloat 16 | let path: CGPath? 17 | 18 | public static let none: Shadow = .init() 19 | 20 | public init( 21 | color: CGColor? = nil, 22 | opacity: Float = 0, 23 | offset: CGSize = CGSize(width: 0, height: -3), 24 | radius: CGFloat = 3, 25 | path: CGPath? = nil 26 | ) { 27 | self.color = color 28 | self.opacity = opacity 29 | self.offset = offset 30 | self.radius = radius 31 | self.path = path 32 | } 33 | } 34 | 35 | extension CALayer { 36 | 37 | func apply(_ shadow: Shadow) { 38 | shadowColor = shadow.color 39 | shadowOpacity = shadow.opacity 40 | shadowOffset = shadow.offset 41 | shadowRadius = shadow.radius 42 | shadowPath = shadow.path 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /EachNavigationBar/Classes/EachNavigationItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EachNavigationItem.swift 3 | // EachNavigationBar 4 | // 5 | // Created by Pircate(gao497868860@gmail.com) on 2019/12/18. 6 | // Copyright © 2019年 Pircate. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class EachNavigationItem: UINavigationItem { 12 | 13 | /// 记录修改过的属性 14 | var changed: Set> = [] 15 | 16 | private weak var viewController: UIViewController? 17 | 18 | convenience init(viewController: UIViewController?) { 19 | self.init() 20 | self.changed = [] 21 | self.viewController = viewController 22 | } 23 | 24 | override var title: String? { 25 | didSet { viewController?.navigationItem.title = title } 26 | } 27 | 28 | override var largeTitleDisplayMode: UINavigationItem.LargeTitleDisplayMode { 29 | get { super.largeTitleDisplayMode } 30 | set { 31 | super.largeTitleDisplayMode = newValue 32 | 33 | viewController?.navigationItem.largeTitleDisplayMode = newValue 34 | 35 | changed.insert(\.largeTitleDisplayMode) 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Example/EachNavigationBar/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIUserInterfaceStyle 28 | Light 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Example/EachNavigationBar/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // EachNavigationBar 4 | // 5 | // Created by Pircate on 04/19/2018. 6 | // Copyright (c) 2018 Pircate. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import EachNavigationBar 11 | 12 | @UIApplicationMain 13 | class AppDelegate: UIResponder, UIApplicationDelegate { 14 | 15 | var window: UIWindow? 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | 19 | window = UIWindow(frame: UIScreen.main.bounds) 20 | window?.backgroundColor = UIColor.white 21 | let nav = UINavigationController(rootViewController: MainViewController()) 22 | 23 | // config 24 | nav.navigation.configuration.isEnabled = true 25 | nav.navigation.configuration.barTintColor = UIColor.green 26 | nav.navigation.configuration.tintColor = UIColor.white 27 | 28 | let shadow = Shadow( 29 | color: UIColor.black.cgColor, 30 | opacity: 0.5, 31 | offset: CGSize(width: 0, height: 3) 32 | ) 33 | nav.navigation.configuration.shadow = shadow 34 | 35 | window?.rootViewController = nav 36 | window?.makeKeyAndVisible() 37 | return true 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /EachNavigationBar/Classes/UITableViewController+EachNavigationBar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UITableViewController+EachNavigationBar.swift 3 | // EachNavigationBar 4 | // 5 | // Created by Pircate(gao497868860@gmail.com) on 2018/10/27. 6 | // Copyright © 2018年 Pircate. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UITableViewController { 12 | 13 | private var observation: NSKeyValueObservation { 14 | let observer = withUnsafePointer(to: &AssociatedKeys.observation) { 15 | objc_getAssociatedObject(self, $0) as? NSKeyValueObservation 16 | } 17 | 18 | if let observer { 19 | return observer 20 | } 21 | 22 | let observation = tableView.observe( 23 | \.contentOffset, 24 | options: .new 25 | ) { [weak self] tableView, _ in 26 | guard let `self` = self else { return } 27 | 28 | self.view.bringSubviewToFront(self._navigationBar) 29 | self._navigationBar.frame.origin.y = tableView.contentOffset.y + self._navigationBar.barMinY 30 | } 31 | 32 | withUnsafePointer(to: &AssociatedKeys.observation) { 33 | objc_setAssociatedObject( 34 | self, 35 | $0, 36 | observation, 37 | .OBJC_ASSOCIATION_RETAIN_NONATOMIC 38 | ) 39 | } 40 | 41 | return observation 42 | } 43 | 44 | func observeContentOffset() { 45 | _navigationBar.automaticallyAdjustsPosition = false 46 | 47 | _ = observation 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /EachNavigationBar/Classes/UINavigationController+EachNavigationBar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationController+EachNavigationBar.swift 3 | // EachNavigationBar 4 | // 5 | // Created by Pircate(gao497868860@gmail.com) on 2018/10/27 6 | // Copyright © 2018年 Pircate. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UINavigationController { 12 | 13 | open override func viewWillLayoutSubviews() { 14 | super.viewWillLayoutSubviews() 15 | 16 | guard _configuration.isEnabled else { return } 17 | 18 | sendNavigationBarToBack() 19 | 20 | guard let bar = topViewController?._navigationBar else { return } 21 | 22 | isNavigationBarHidden = false 23 | navigationBar.isHidden = bar.isHidden 24 | 25 | bar.adjustsLayout() 26 | 27 | topViewController?.adjustsSafeAreaInsets() 28 | } 29 | 30 | open override func viewDidLayoutSubviews() { 31 | super.viewDidLayoutSubviews() 32 | 33 | guard _configuration.isEnabled else { return } 34 | 35 | topViewController?._navigationBar.adjustsLayout() 36 | } 37 | 38 | func sendNavigationBarToBack() { 39 | navigationBar.tintColor = UIColor.clear 40 | if navigationBar.shadowImage == nil { 41 | let image = UIImage() 42 | navigationBar.setBackgroundImage(image, for: .default) 43 | navigationBar.shadowImage = image 44 | navigationBar.backIndicatorImage = image 45 | navigationBar.backIndicatorTransitionMaskImage = image 46 | } 47 | view.sendSubviewToBack(navigationBar) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /EachNavigationBar/Classes/UINavigationBar+Sugar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationBar+Sugar.swift 3 | // EachNavigationBar 4 | // 5 | // Created by Pircate(gao497868860@gmail.com) on 2018/10/30 6 | // Copyright © 2018年 Pircate. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public extension UINavigationBar { 12 | 13 | func setTitleAlpha(_ alpha: CGFloat) { 14 | let color = titleTextAttributes?[.foregroundColor] as? UIColor ?? defaultTitleColor 15 | setTitleColor(color.withAlphaComponent(alpha)) 16 | } 17 | 18 | func setLargeTitleAlpha(_ alpha: CGFloat) { 19 | let color = largeTitleTextAttributes?[.foregroundColor] as? UIColor ?? defaultTitleColor 20 | setLargeTitleColor(color.withAlphaComponent(alpha)) 21 | } 22 | 23 | func setTintAlpha(_ alpha: CGFloat) { 24 | tintColor = tintColor.withAlphaComponent(alpha) 25 | } 26 | } 27 | 28 | private extension UINavigationBar { 29 | 30 | var defaultTitleColor: UIColor { 31 | return barStyle == .default ? UIColor.black : UIColor.white 32 | } 33 | 34 | func setTitleColor(_ color: UIColor) { 35 | if var titleTextAttributes = titleTextAttributes { 36 | titleTextAttributes[.foregroundColor] = color 37 | self.titleTextAttributes = titleTextAttributes 38 | } else { 39 | titleTextAttributes = [.foregroundColor: color] 40 | } 41 | } 42 | 43 | func setLargeTitleColor(_ color: UIColor) { 44 | if var largeTitleTextAttributes = largeTitleTextAttributes { 45 | largeTitleTextAttributes[.foregroundColor] = color 46 | self.largeTitleTextAttributes = largeTitleTextAttributes 47 | } else { 48 | self.largeTitleTextAttributes = [.foregroundColor: color] 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /EachNavigationBar/Classes/BackBarButtonItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BackBarButtonItem.swift 3 | // EachNavigationBar 4 | // 5 | // Created by Pircate(gao497868860@gmail.com) on 2018/12/20 6 | // Copyright © 2018年 Pircate. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | open class BackBarButtonItem: UIBarButtonItem { 12 | 13 | public var shouldBack: (BackBarButtonItem) -> Bool = { _ in true } 14 | 15 | public var willBack: () -> Void = {} 16 | 17 | public var didBack: () -> Void = {} 18 | 19 | weak var navigationController: UINavigationController? 20 | } 21 | 22 | public extension BackBarButtonItem { 23 | 24 | convenience init(style: ItemStyle, tintColor: UIColor? = nil) { 25 | let action = #selector(backBarButtonItemAction) 26 | 27 | switch style { 28 | case .title(let title): 29 | self.init(title: title, style: .plain, target: nil, action: action) 30 | 31 | self.target = self 32 | self.tintColor = tintColor 33 | case .image(let image): 34 | self.init(image: image, style: .plain, target: nil, action: action) 35 | 36 | self.target = self 37 | self.tintColor = tintColor 38 | case .custom(let button): 39 | self.init(customView: button) 40 | 41 | button.addTarget(self, action: action, for: .touchUpInside) 42 | button.tintColor = tintColor 43 | } 44 | } 45 | 46 | func goBack() { 47 | navigationController?.popViewController(animated: true) 48 | } 49 | } 50 | 51 | extension BackBarButtonItem { 52 | 53 | public enum ItemStyle { 54 | case title(String?) 55 | case image(UIImage?) 56 | case custom(UIButton) 57 | } 58 | } 59 | 60 | extension BackBarButtonItem { 61 | 62 | @objc private func backBarButtonItemAction() { 63 | guard shouldBack(self) else { return } 64 | 65 | willBack() 66 | goBack() 67 | didBack() 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Example/EachNavigationBar/NextViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NextViewController.swift 3 | // UIViewController+NavigationBar 4 | // 5 | // Created by Pircate on 2018/3/26. 6 | // Copyright © 2018年 Pircate. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class NextViewController: UIViewController { 12 | 13 | private lazy var scrollView: UIScrollView = { 14 | let scrollView = UIScrollView(frame: view.bounds) 15 | scrollView.contentSize = CGSize(width: view.bounds.width, height: 1000) 16 | scrollView.delegate = self 17 | return scrollView 18 | }() 19 | 20 | private lazy var tipLabel: UILabel = { 21 | let lable = UILabel(frame: CGRect(x: 0, y: 0, width: 120, height: 20)) 22 | lable.center = view.center 23 | lable.textAlignment = .center 24 | lable.text = "上下滑动试试" 25 | return lable 26 | }() 27 | 28 | override func viewDidLoad() { 29 | super.viewDidLoad() 30 | 31 | view.backgroundColor = UIColor.white 32 | view.addSubview(scrollView) 33 | view.addSubview(tipLabel) 34 | 35 | navigation.item.title = "Next" 36 | navigation.bar.tintColor = nil 37 | 38 | let titleView = UITextField(frame: CGRect(x: 0, y: 0, width: view.bounds.width - 100, height: 30)) 39 | titleView.backgroundColor = UIColor.lightGray 40 | titleView.layer.cornerRadius = 15 41 | titleView.layer.masksToBounds = true 42 | navigation.item.titleView = titleView 43 | navigation.bar.prefersLargeTitles = false 44 | 45 | navigation.bar.backBarButtonItem?.shouldBack = { item in 46 | let alert = UIAlertController(title: "确定退出", message: nil, preferredStyle: .alert) 47 | alert.addAction(UIAlertAction(title: "取消", style: .cancel, handler: nil)) 48 | alert.addAction(UIAlertAction(title: "确定", style: .default) { _ in 49 | item.goBack() 50 | }) 51 | self.present(alert, animated: true, completion: nil) 52 | debugPrint("shouldBack") 53 | return false 54 | } 55 | } 56 | 57 | @objc private func backBarButtonAction() { 58 | navigationController?.popViewController(animated: true) 59 | } 60 | } 61 | 62 | extension NextViewController: UIScrollViewDelegate { 63 | func scrollViewDidScroll(_ scrollView: UIScrollView) { 64 | let alpha = 1 - (scrollView.contentOffset.y) / (scrollView.contentSize.height - view.bounds.height) 65 | navigation.bar.alpha = alpha 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /EachNavigationBar/Classes/UIViewController+Swizzling.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+Swizzling.swift 3 | // EachNavigationBar 4 | // 5 | // Created by Pircate(gao497868860@gmail.com) on 2018/11/22 6 | // Copyright © 2018年 Pircate. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | infix operator <=> 12 | 13 | extension UIViewController { 14 | 15 | static let methodSwizzling: Void = { 16 | #selector(viewDidLoad) <=> #selector(navigation_viewDidLoad) 17 | #selector(viewWillAppear(_:)) <=> #selector(navigation_viewWillAppear(_:)) 18 | #selector(setNeedsStatusBarAppearanceUpdate) <=> #selector(navigation_setNeedsStatusBarAppearanceUpdate) 19 | #selector(viewDidLayoutSubviews) <=> #selector(navigation_viewDidLayoutSubviews) 20 | }() 21 | 22 | private var isNavigationBarEnabled: Bool { 23 | guard let navigationController = navigationController, 24 | navigationController.navigation.configuration.isEnabled, 25 | navigationController.viewControllers.contains(self) else { 26 | return false 27 | } 28 | 29 | return true 30 | } 31 | 32 | @objc private func navigation_viewDidLoad() { 33 | navigation_viewDidLoad() 34 | 35 | guard isNavigationBarEnabled else { return } 36 | 37 | setupNavigationBarWhenViewDidLoad() 38 | 39 | if let tableViewController = self as? UITableViewController { 40 | tableViewController.observeContentOffset() 41 | } 42 | } 43 | 44 | @objc private func navigation_viewWillAppear(_ animated: Bool) { 45 | navigation_viewWillAppear(animated) 46 | 47 | guard isNavigationBarEnabled else { return } 48 | 49 | updateNavigationBarWhenViewWillAppear() 50 | } 51 | 52 | @objc private func navigation_setNeedsStatusBarAppearanceUpdate() { 53 | navigation_setNeedsStatusBarAppearanceUpdate() 54 | 55 | adjustsNavigationBarLayout() 56 | } 57 | 58 | @objc private func navigation_viewDidLayoutSubviews() { 59 | navigation_viewDidLayoutSubviews() 60 | 61 | view.bringSubviewToFront(_navigationBar) 62 | } 63 | } 64 | 65 | private extension Selector { 66 | 67 | static func <=> (left: Selector, right: Selector) { 68 | if let originalMethod = class_getInstanceMethod(UIViewController.self, left), 69 | let swizzledMethod = class_getInstanceMethod(UIViewController.self, right) { 70 | method_exchangeImplementations(originalMethod, swizzledMethod) 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Example/EachNavigationBar/MainViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MainViewController.swift 3 | // EachNavigationBar_Example 4 | // 5 | // Created by Pircate(gao497868860@gmail.com) on 2018/10/29 6 | // Copyright © 2018 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class MainViewController: UIViewController { 12 | 13 | @IBOutlet weak var setLargeTitleAlphaSlider: UISlider! 14 | 15 | override var prefersStatusBarHidden: Bool { 16 | return isStatusBarHidden 17 | } 18 | 19 | private var isStatusBarHidden: Bool = false 20 | 21 | override func viewDidLoad() { 22 | super.viewDidLoad() 23 | 24 | navigation.item.title = "EachNavigationBar" 25 | navigation.item.rightBarButtonItem = UIBarButtonItem( 26 | title: "Next", 27 | style: .plain, 28 | target: self, 29 | action: #selector(rightBarButtonAction) 30 | ) 31 | 32 | navigation.bar.shadow = .none 33 | } 34 | 35 | @objc private func rightBarButtonAction() { 36 | navigationController?.pushViewController(ViewController(), animated: true) 37 | } 38 | 39 | @IBAction func isHiddenAction(_ sender: UISwitch) { 40 | navigation.bar.isHidden = sender.isOn 41 | } 42 | 43 | @IBAction func setAlphaAction(_ sender: UISlider) { 44 | navigation.bar.alpha = CGFloat(sender.value) 45 | } 46 | 47 | @IBAction func setTitleAlphaAction(_ sender: UISlider) { 48 | navigation.bar.setTitleAlpha(CGFloat(sender.value)) 49 | } 50 | 51 | @IBAction func isShadowHiddenAction(_ sender: UISwitch) { 52 | navigation.bar.isShadowHidden = sender.isOn 53 | } 54 | 55 | @IBAction func extraHeightAction(_ sender: UISlider) { 56 | navigation.bar.additionalHeight = CGFloat(sender.value) 57 | } 58 | 59 | @IBAction func prefersLargetTitleAction(_ sender: UISwitch) { 60 | navigation.bar.prefersLargeTitles = sender.isOn 61 | navigation.item.largeTitleDisplayMode = sender.isOn ? .always : .never 62 | setLargeTitleAlphaSlider.isEnabled = sender.isOn 63 | } 64 | 65 | @IBAction func setLargeTitleAlphaAction(_ sender: UISlider) { 66 | navigation.bar.setLargeTitleAlpha(CGFloat(sender.value)) 67 | } 68 | 69 | @IBAction func changeStatusBarStyle(_ sender: UISwitch) { 70 | navigation.bar.statusBarStyle = sender.isOn ? .lightContent : .default 71 | } 72 | 73 | @IBAction func isStatusBarHiddenAction(_ sender: UISwitch) { 74 | isStatusBarHidden = sender.isOn 75 | setNeedsStatusBarAppearanceUpdate() 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /EachNavigationBar/Classes/UIViewController+Associated.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+Associated.swift 3 | // EachNavigationBar 4 | // 5 | // Created by Pircate(gao497868860@gmail.com) on 2018/12/22 6 | // Copyright © 2018年 Pircate. All rights reserved. 7 | // 8 | 9 | import ObjectiveC 10 | import UIKit 11 | 12 | extension UINavigationController { 13 | 14 | var _configuration: Configuration { 15 | let config = withUnsafePointer(to: &AssociatedKeys.configuration) { 16 | objc_getAssociatedObject(self, $0) as? Configuration 17 | } 18 | 19 | if let config { 20 | return config 21 | } 22 | 23 | let configuration = Configuration() 24 | 25 | withUnsafePointer(to: &AssociatedKeys.configuration) { 26 | objc_setAssociatedObject( 27 | self, 28 | $0, 29 | configuration, 30 | .OBJC_ASSOCIATION_RETAIN_NONATOMIC 31 | ) 32 | } 33 | 34 | return configuration 35 | } 36 | } 37 | 38 | extension UIViewController { 39 | 40 | var _navigationBar: EachNavigationBar { 41 | let bar = withUnsafePointer(to: &AssociatedKeys.navigationBar) { 42 | objc_getAssociatedObject(self, $0) as? EachNavigationBar 43 | } 44 | 45 | if let bar { 46 | return bar 47 | } 48 | 49 | let navigationBar = EachNavigationBar(viewController: self) 50 | 51 | withUnsafePointer(to: &AssociatedKeys.navigationBar) { 52 | objc_setAssociatedObject( 53 | self, 54 | $0, 55 | navigationBar, 56 | .OBJC_ASSOCIATION_RETAIN_NONATOMIC 57 | ) 58 | } 59 | 60 | return navigationBar 61 | } 62 | 63 | var _navigationItem: EachNavigationItem { 64 | let item = withUnsafePointer(to: &AssociatedKeys.navigationItem) { 65 | objc_getAssociatedObject(self, $0) as? EachNavigationItem 66 | } 67 | 68 | if let item { 69 | return item 70 | } 71 | 72 | let navigationItem = EachNavigationItem(viewController: self) 73 | navigationItem.copy(by: navigationItem) 74 | 75 | withUnsafePointer(to: &AssociatedKeys.navigationItem) { 76 | objc_setAssociatedObject( 77 | self, 78 | $0, 79 | navigationItem, 80 | .OBJC_ASSOCIATION_RETAIN_NONATOMIC 81 | ) 82 | } 83 | 84 | return navigationItem 85 | } 86 | } 87 | 88 | private extension UINavigationItem { 89 | 90 | func copy(by navigationItem: UINavigationItem) { 91 | self.title = navigationItem.title 92 | self.prompt = navigationItem.prompt 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Example/EachNavigationBar/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // EachNavigationBar 4 | // 5 | // Created by Pircate on 04/19/2018. 6 | // Copyright (c) 2018 Pircate. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | private lazy var scrollView: UIScrollView = { 14 | let scrollView = UIScrollView(frame: view.bounds) 15 | scrollView.contentSize = CGSize(width: view.bounds.width, height: 1000) 16 | scrollView.delegate = self 17 | return scrollView 18 | }() 19 | 20 | private lazy var tipLabel: UILabel = { 21 | let lable = UILabel(frame: CGRect(x: 0, y: 0, width: 120, height: 20)) 22 | lable.center = view.center 23 | lable.textAlignment = .center 24 | lable.text = "上下滑动试试" 25 | return lable 26 | }() 27 | 28 | override func viewDidLoad() { 29 | super.viewDidLoad() 30 | 31 | view.backgroundColor = UIColor.white 32 | view.addSubview(scrollView) 33 | view.addSubview(tipLabel) 34 | 35 | navigation.bar.statusBarStyle = .lightContent 36 | navigation.bar.setBackgroundImage(#imageLiteral(resourceName: "nav"), for: .default) 37 | 38 | navigation.item.rightBarButtonItem = UIBarButtonItem( 39 | barButtonSystemItem: .done, 40 | target: self, 41 | action: #selector(rightBarButtonAction)) 42 | navigation.item.title = "Home" 43 | navigation.bar.titleTextAttributes = [ 44 | .foregroundColor: UIColor.blue, 45 | .font: UIFont.systemFont(ofSize: 24) 46 | ] 47 | 48 | navigation.bar.backBarButtonItem?.willBack = { 49 | debugPrint("willBack") 50 | } 51 | navigation.bar.backBarButtonItem?.didBack = { 52 | debugPrint("didBack") 53 | } 54 | 55 | // if you want change navigation bar position 56 | navigation.bar.automaticallyAdjustsPosition = false 57 | } 58 | 59 | @objc private func rightBarButtonAction() { 60 | navigationController?.pushViewController(NextViewController(), animated: true) 61 | } 62 | } 63 | 64 | extension ViewController: UIScrollViewDelegate { 65 | func scrollViewDidScroll(_ scrollView: UIScrollView) { 66 | guard let nav = navigationController else { 67 | return 68 | } 69 | 70 | let statusBarMaxY = nav.navigationBar.frame.minY 71 | let originY = -scrollView.contentOffset.y + statusBarMaxY 72 | let alpha = 1 - (scrollView.contentOffset.y) / navigation.bar.frame.height 73 | navigation.bar.setTintAlpha(alpha) 74 | navigation.bar.setTitleAlpha(alpha) 75 | navigation.bar.setLargeTitleAlpha(alpha) 76 | if originY <= statusBarMaxY { 77 | let minY = statusBarMaxY - navigation.bar.frame.height 78 | navigation.bar.frame.origin.y = originY > minY ? originY : minY 79 | } else { 80 | navigation.bar.setLargeTitleAlpha(1) 81 | navigation.bar.setTitleAlpha(1) 82 | navigation.bar.setTintAlpha(1) 83 | navigation.bar.frame.origin.y = statusBarMaxY 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /EachNavigationBar/Classes/Configuration.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationController+Configuration.swift 3 | // EachNavigationBar 4 | // 5 | // Created by Pircate(gao497868860@gmail.com) on 2018/6/26. 6 | // Copyright © 2018年 Pircate. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UINavigationController { 12 | 13 | public final class Configuration { 14 | 15 | public var isEnabled = false { 16 | didSet { UIViewController.methodSwizzling } 17 | } 18 | 19 | public var isHidden = false 20 | 21 | public var alpha: CGFloat = 1 22 | 23 | public var barTintColor: UIColor? 24 | 25 | public var tintColor: UIColor? 26 | 27 | public var shadow: Shadow? 28 | 29 | public var shadowImage: UIImage? 30 | 31 | // Hides shadow image. 32 | public var isShadowHidden: Bool = false 33 | 34 | public var titleTextAttributes: [NSAttributedString.Key: Any]? 35 | 36 | public var isTranslucent: Bool = true 37 | 38 | public var barStyle: UIBarStyle = .default 39 | 40 | public var statusBarStyle: UIStatusBarStyle = .default 41 | 42 | /// Additional height for the navigation bar. 43 | public var additionalHeight: CGFloat = 0 44 | 45 | public var backItem: BackItem? 46 | 47 | var background: Background = .init() 48 | 49 | private var _layoutPaddings: UIEdgeInsets = .barLayoutPaddings 50 | 51 | private var _prefersLargeTitles: Bool = false 52 | 53 | private var _largeTitle: LargeTitle = .init() 54 | } 55 | } 56 | 57 | public extension UINavigationController.Configuration { 58 | 59 | /// Padding of navigation bar content view. 60 | var layoutPaddings: UIEdgeInsets { 61 | get { _layoutPaddings } 62 | set { _layoutPaddings = newValue } 63 | } 64 | 65 | var prefersLargeTitles: Bool { 66 | get { _prefersLargeTitles } 67 | set { _prefersLargeTitles = newValue } 68 | } 69 | 70 | var largeTitle: LargeTitle { 71 | get { _largeTitle } 72 | set { _largeTitle = newValue } 73 | } 74 | 75 | func setBackgroundImage( 76 | _ backgroundImage: UIImage?, 77 | for barPosition: UIBarPosition = .any, 78 | barMetrics: UIBarMetrics = .default 79 | ) { 80 | self.background.image = backgroundImage 81 | self.background.barPosition = barPosition 82 | self.background.barMetrics = barMetrics 83 | } 84 | } 85 | 86 | extension UINavigationController.Configuration { 87 | 88 | public struct BackItem { 89 | public let style: Style 90 | public let tintColor: UIColor? 91 | 92 | public enum Style { 93 | case title(String?) 94 | case image(UIImage?) 95 | } 96 | 97 | public init(style: Style, tintColor: UIColor? = nil) { 98 | self.style = style 99 | self.tintColor = tintColor 100 | } 101 | } 102 | 103 | public struct LargeTitle { 104 | public var textAttributes: [NSAttributedString.Key: Any]? 105 | public var displayMode: UINavigationItem.LargeTitleDisplayMode = .automatic 106 | } 107 | 108 | struct Background { 109 | var image: UIImage? 110 | var barMetrics: UIBarMetrics = .default 111 | var barPosition: UIBarPosition = .any 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /Example/EachNavigationBar/TableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TableViewController.swift 3 | // EachNavigationBar_Example 4 | // 5 | // Created by Pircate(gao497868860@gmail.com) on 2018/10/27 6 | // Copyright © 2018 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TableViewController: UITableViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | // Uncomment the following line to preserve selection between presentations 17 | // self.clearsSelectionOnViewWillAppear = false 18 | 19 | // Uncomment the following line to display an Edit button in the navigation bar for this view controller. 20 | // self.navigationItem.rightBarButtonItem = self.editButtonItem 21 | tableView.register(UITableViewCell.self, forCellReuseIdentifier: "reuseIdentifier") 22 | } 23 | 24 | // MARK: - Table view data source 25 | 26 | override func numberOfSections(in tableView: UITableView) -> Int { 27 | // #warning Incomplete implementation, return the number of sections 28 | return 10 29 | } 30 | 31 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 32 | // #warning Incomplete implementation, return the number of rows 33 | return 3 34 | } 35 | 36 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 37 | let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath) 38 | 39 | // Configure the cell... 40 | 41 | return cell 42 | } 43 | 44 | override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 45 | return 30 46 | } 47 | 48 | override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 49 | let view = UIView() 50 | view.backgroundColor = UIColor.red 51 | return view 52 | } 53 | 54 | /* 55 | // Override to support conditional editing of the table view. 56 | override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { 57 | // Return false if you do not want the specified item to be editable. 58 | return true 59 | } 60 | */ 61 | 62 | /* 63 | // Override to support editing the table view. 64 | override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { 65 | if editingStyle == .delete { 66 | // Delete the row from the data source 67 | tableView.deleteRows(at: [indexPath], with: .fade) 68 | } else if editingStyle == .insert { 69 | // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view 70 | } 71 | } 72 | */ 73 | 74 | /* 75 | // Override to support rearranging the table view. 76 | override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) { 77 | 78 | } 79 | */ 80 | 81 | /* 82 | // Override to support conditional rearranging of the table view. 83 | override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { 84 | // Return false if you do not want the item to be re-orderable. 85 | return true 86 | } 87 | */ 88 | 89 | /* 90 | // MARK: - Navigation 91 | 92 | // In a storyboard-based application, you will often want to do a little preparation before navigation 93 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 94 | // Get the new view controller using segue.destination. 95 | // Pass the selected object to the new view controller. 96 | } 97 | */ 98 | 99 | } 100 | -------------------------------------------------------------------------------- /Example/EachNavigationBar/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /README_CN.md: -------------------------------------------------------------------------------- 1 | # EachNavigationBar 2 | 3 | [![Lint](https://github.com/Pircate/EachNavigationBar/workflows/Lint/badge.svg)](https://github.com/Pircate/EachNavigationBar/actions?query=workflow%3ALint) 4 | [![Version](https://img.shields.io/cocoapods/v/EachNavigationBar.svg?style=flat)](http://cocoapods.org/pods/EachNavigationBar) 5 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 6 | [![License](https://img.shields.io/cocoapods/l/EachNavigationBar.svg?style=flat)](http://cocoapods.org/pods/EachNavigationBar) 7 | [![Platform](https://img.shields.io/cocoapods/p/EachNavigationBar.svg?style=flat)](https://cocoapods.org/pods/EachNavigationBar) 8 | 9 | ## 示例 10 | 11 | 要运行示例项目,首先克隆 repo 并在 Example 目录运行 `pod install`。 12 | 13 | ## 版本要求 14 | 15 | * iOS 9.0 16 | * Swift 4.2 17 | 18 | ## 安装 19 | 20 | EachNavigationBar 可通过 [CocoaPods](http://cocoapods.org) 或者 [Carthage](https://github.com/Carthage/Carthage) 安装, 简单的添加下面一行到你的 Podfile 或者 Cartfile: 21 | 22 | ### Podfile 23 | 24 | ```ruby 25 | pod 'EachNavigationBar' 26 | ``` 27 | 28 | ### Cartfile 29 | ```ruby 30 | github "Pircate/EachNavigationBar" 31 | ``` 32 | 33 | ## 预览 34 | 35 | ![](https://github.com/Pircate/EachNavigationBar/blob/master/demo_new.gif) 36 | ![](https://github.com/Pircate/EachNavigationBar/blob/master/demo_push.gif) 37 | 38 | ## 用法 39 | 40 | ### 导入 41 | 42 | Swift 43 | ``` swift 44 | import EachNavigationBar 45 | ``` 46 | 47 | ### 开启 48 | 49 | 给当前导航栈的 viewControllers 添加一个独立的导航栏。 50 | 51 | 只对当前导航栈有效,不影响其他导航栈。 52 | 53 | ``` swift 54 | let nav = UINavigationController(rootViewController: vc) 55 | nav.navigation.configuration.isEnabled = true 56 | ``` 57 | 58 | ### 设置 59 | #### 导航栈全局配置 60 | 61 | 不要通过 navigationController.navigationBar 去设置全局属性!!! 62 | 63 | 更多配置请看[这里](https://github.com/Pircate/EachNavigationBar/blob/master/EachNavigationBar/Classes/Configuration.swift) 64 | 65 | ``` swift 66 | nav.navigation.configuration.titleTextAttributes = [.foregroundColor: UIColor.blue] 67 | 68 | nav.navigation.configuration.barTintColor = UIColor.red 69 | 70 | nav.navigation.configuration.shadowImage = UIImage(named: "shadow") 71 | 72 | nav.navigation.configuration.setBackgroundImage(UIImage(named: "nav"), for: .any, barMetrics: .default) 73 | 74 | nav.navigation.configuration.backItem = UINavigationController.Configuration.BackItem(style: .title("返回")) 75 | 76 | nav.navigation.configuration.prefersLargeTitles = true 77 | 78 | nav.navigation.configuration.largeTitle.displayMode = .always 79 | ``` 80 | 81 | #### 每个控制器设置 82 | ##### 普通设置 83 | 84 | ``` swift 85 | // 一般用法同系统组件 86 | navigation.bar -> EachNavigationBar -> UINavigationBar 87 | navigation.item -> UINavigationItem 88 | 89 | // 隐藏导航栏 90 | navigation.bar.isHidden = true 91 | 92 | // 设置导航栏透明度 93 | navigation.bar.alpha = 0.5 94 | 95 | // 设置标题透明度 96 | navigation.bar.setTitleAlpha(0.5) 97 | 98 | // 设置 barButtonItem 透明度 99 | navigation.bar.setTintAlpha(0.5) 100 | // 如果 barButtonItem 是自定义视图 101 | navigation.item.leftBarButtonItem?.customView?.alpha = 0.5 102 | // 如果 barButtonItem 自定义了 tintColor 103 | navigation.item.leftBarButtonItem?.tintColor = navigation.item.leftBarButtonItem?.tintColor?.withAlphaComponent(0.5) 104 | 105 | // 移除毛玻璃效果 106 | navigation.bar.isTranslucent = false 107 | 108 | // 隐藏底部阴影 109 | navigation.bar.isShadowHidden = true 110 | 111 | // 设置状态栏样式 112 | navigation.bar.statusBarStyle = .lightContent 113 | 114 | // 设置返回按钮 115 | navigation.bar.backBarButtonItem = .init(style: .title("Back"), tintColor: .red) 116 | 117 | // 允许返回事件 118 | navigation.bar.backBarButtonItem.shouldBack = { item in 119 | // do something 120 | return false 121 | } 122 | 123 | // 返回事件之前回调 124 | navigation.bar.backBarButtonItem.willBack = { 125 | // do something 126 | } 127 | 128 | // 返回事件之后回调 129 | navigation.bar.backBarButtonItem.didBack = { 130 | // do something 131 | } 132 | 133 | // 如果想自定义导航栏位置,请将下面属性设为 false 134 | navigation.bar.automaticallyAdjustsPosition = false 135 | 136 | // 导航栏附加高度 137 | navigation.bar.additionalHeight = 14 138 | 139 | // 导航栏附加视图 140 | navigation.bar.additionalView = UIView() 141 | 142 | // 导航栏阴影 143 | navigation.bar.shadow = Shadow( 144 | color: UIColor.black.cgColor, 145 | opacity: 0.5, 146 | offset: CGSize(width: 0, height: 3)) 147 | ``` 148 | 149 | ##### 大标题设置(iOS 11.0+) 150 | 151 | ``` swift 152 | // 开启大标题 153 | navigation.bar.prefersLargeTitles = true 154 | 155 | // 显示模式 156 | navigation.item.largeTitleDisplayMode = .always 157 | 158 | // 设置大标题透明度 159 | navigation.bar.setLargeTitleAlpha(0.5) 160 | ``` 161 | 162 | #### 关于约束 163 | 164 | 和使用系统导航栏完全一致。 165 | 166 | * 请注意 iOS 11 以上和以下的区别。 167 | * 如果使用 XIB 请参看[这篇文章](https://www.jianshu.com/p/ba9bb519f07f),应该会有帮助。 168 | * [SnapKit](https://github.com/SnapKit/SnapKit) 用户可以试试这个 [extension](https://gist.github.com/Pircate/52a3aeb2c59695f6e997a6f3bd19242b)。 169 | 170 | ## 作者 171 | 172 | Pircate, gao497868860@163.com 173 | 174 | ## 许可证 175 | 176 | EachNavigationBar 可在 MIT 许可证下使用。有关更多信息,请参阅许可证文件。 177 | -------------------------------------------------------------------------------- /Example/EachNavigationBar.xcodeproj/xcuserdata/pircate.xcuserdatad/xcschemes/EachNavigationBar-Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 51 | 52 | 53 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 76 | 78 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EachNavigationBar 2 | 3 | [![Lint](https://github.com/Pircate/EachNavigationBar/workflows/Lint/badge.svg)](https://github.com/Pircate/EachNavigationBar/actions?query=workflow%3ALint) 4 | [![Version](https://img.shields.io/cocoapods/v/EachNavigationBar.svg?style=flat)](http://cocoapods.org/pods/EachNavigationBar) 5 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 6 | [![License](https://img.shields.io/cocoapods/l/EachNavigationBar.svg?style=flat)](http://cocoapods.org/pods/EachNavigationBar) 7 | [![Platform](https://img.shields.io/cocoapods/p/EachNavigationBar.svg?style=flat)](https://cocoapods.org/pods/EachNavigationBar) 8 | [![中文文档](https://woolson.gitee.io/npmer-badge/-007ec6-%E4%B8%AD%E6%96%87%E6%96%87%E6%A1%A3-007ec6-github-ffffff-square-gradient-shadow.svg)](https://github.com/Pircate/EachNavigationBar/blob/master/README_CN.md) 9 | 10 | [中文文档](https://github.com/Pircate/EachNavigationBar/blob/master/README_CN.md) 11 | 12 | ## Example 13 | 14 | To run the example project, clone the repo, and run `pod install` from the Example directory first. 15 | 16 | ## Requirements 17 | 18 | * iOS 9.0 19 | * Swift 4.2 20 | 21 | ## Installation 22 | 23 | EachNavigationBar is available through [CocoaPods](http://cocoapods.org) or [Carthage](https://github.com/Carthage/Carthage). To install 24 | it, simply add the following line to your Podfile or Cartfile: 25 | 26 | #### Podfile 27 | 28 | ```ruby 29 | pod 'EachNavigationBar' 30 | ``` 31 | 32 | #### Cartfile 33 | ```ruby 34 | github "Pircate/EachNavigationBar" 35 | ``` 36 | 37 | ## Overview 38 | 39 | ![](https://github.com/Pircate/EachNavigationBar/blob/master/demo_new.gif) 40 | ![](https://github.com/Pircate/EachNavigationBar/blob/master/demo_push.gif) 41 | 42 | ## Usage 43 | 44 | ### Import 45 | 46 | ``` swift 47 | import EachNavigationBar 48 | ``` 49 | 50 | ### Enable 51 | 52 | ``` swift 53 | let nav = UINavigationController(rootViewController: vc) 54 | nav.navigation.configuration.isEnabled = true 55 | ``` 56 | 57 | ### Setting 58 | #### Global 59 | 60 | ``` swift 61 | nav.navigation.configuration.titleTextAttributes = [.foregroundColor: UIColor.blue] 62 | 63 | nav.navigation.configuration.barTintColor = UIColor.red 64 | 65 | nav.navigation.configuration.shadowImage = UIImage(named: "shadow") 66 | 67 | nav.navigation.configuration.setBackgroundImage(UIImage(named: "nav"), for: .any, barMetrics: .default) 68 | 69 | nav.navigation.configuration.backItem = UINavigationController.Configuration.BackItem(style: .title("返回")) 70 | 71 | nav.navigation.configuration.prefersLargeTitles = true 72 | 73 | nav.navigation.configuration.largeTitle.displayMode = .always 74 | ``` 75 | 76 | #### Each view controller 77 | 78 | ##### Normal 79 | 80 | ``` swift 81 | navigation.bar -> EachNavigationBar -> UINavigationBar 82 | navigation.item -> UINavigationItem 83 | 84 | // hide navigation bar 85 | navigation.bar.isHidden = true 86 | 87 | // remove blur effect 88 | navigation.bar.isTranslucent = false 89 | 90 | // hides shadow image 91 | navigation.bar.isShadowHidden = true 92 | 93 | // set status bar style 94 | navigation.bar.statusBarStyle = .lightContent 95 | 96 | // if you want change navigation bar position 97 | navigation.bar.automaticallyAdjustsPosition = false 98 | 99 | // item padding 100 | navigation.bar.layoutPaddings = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8) 101 | 102 | // shadow 103 | navigation.bar.shadow = Shadow( 104 | color: UIColor.black.cgColor, 105 | opacity: 0.5, 106 | offset: CGSize(width: 0, height: 3) 107 | ) 108 | ``` 109 | 110 | #### Alpha 111 | ```swift 112 | // set bar alpha 113 | navigation.bar.alpha = 0.5 114 | 115 | // set title alpha 116 | navigation.bar.setTitleAlpha(0.5) 117 | 118 | // set barButtonItem alpha 119 | navigation.bar.setTintAlpha(0.5) 120 | // if barButtonItem is customView 121 | navigation.item.leftBarButtonItem?.customView?.alpha = 0.5 122 | // if barButtonItem customized tintColor 123 | navigation.item.leftBarButtonItem?.tintColor = navigation.item.leftBarButtonItem?.tintColor?.withAlphaComponent(0.5) 124 | ``` 125 | 126 | #### Additional height or view 127 | ```swift 128 | // navigation bar additional height 129 | navigation.bar.additionalHeight = 14 130 | 131 | // navigation bar additional view 132 | navigation.bar.additionalView = UIView() 133 | ``` 134 | 135 | #### BackBarButtonItem 136 | ```swift 137 | // set back bar button item 138 | navigation.bar.backBarButtonItem = .init(style: .title("Back"), tintColor: .red) 139 | 140 | // allow back 141 | navigation.bar.backBarButtonItem.shouldBack = { item in 142 | // do something 143 | return false 144 | } 145 | 146 | // handler before back 147 | navigation.bar.backBarButtonItem.willBack = { 148 | // do something 149 | } 150 | 151 | // handler after back 152 | navigation.bar.backBarButtonItem.didBack = { 153 | // do something 154 | } 155 | 156 | ``` 157 | 158 | #### LargeTitle(iOS 11.0+) 159 | 160 | ``` swift 161 | // enable 162 | navigation.bar.prefersLargeTitles = true 163 | 164 | // display mode 165 | navigation.item.largeTitleDisplayMode = .always 166 | 167 | // alpha 168 | navigation.bar.setLargeTitleAlpha(0.5) 169 | ``` 170 | 171 | ## Author 172 | 173 | Pircate, gao497868860@163.com 174 | 175 | ## License 176 | 177 | EachNavigationBar is available under the MIT license. See the LICENSE file for more info. 178 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.5) 5 | rexml 6 | activesupport (7.0.3) 7 | concurrent-ruby (~> 1.0, >= 1.0.2) 8 | i18n (>= 1.6, < 2) 9 | minitest (>= 5.1) 10 | tzinfo (~> 2.0) 11 | addressable (2.8.0) 12 | public_suffix (>= 2.0.2, < 5.0) 13 | algoliasearch (1.27.5) 14 | httpclient (~> 2.8, >= 2.8.3) 15 | json (>= 1.5.1) 16 | artifactory (3.0.15) 17 | atomos (0.1.3) 18 | aws-eventstream (1.2.0) 19 | aws-partitions (1.825.0) 20 | aws-sdk-core (3.182.0) 21 | aws-eventstream (~> 1, >= 1.0.2) 22 | aws-partitions (~> 1, >= 1.651.0) 23 | aws-sigv4 (~> 1.5) 24 | jmespath (~> 1, >= 1.6.1) 25 | aws-sdk-kms (1.71.0) 26 | aws-sdk-core (~> 3, >= 3.177.0) 27 | aws-sigv4 (~> 1.1) 28 | aws-sdk-s3 (1.134.0) 29 | aws-sdk-core (~> 3, >= 3.181.0) 30 | aws-sdk-kms (~> 1) 31 | aws-sigv4 (~> 1.6) 32 | aws-sigv4 (1.6.0) 33 | aws-eventstream (~> 1, >= 1.0.2) 34 | babosa (1.0.4) 35 | claide (1.1.0) 36 | cocoapods (1.12.0) 37 | addressable (~> 2.8) 38 | claide (>= 1.0.2, < 2.0) 39 | cocoapods-core (= 1.12.0) 40 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 41 | cocoapods-downloader (>= 1.6.0, < 2.0) 42 | cocoapods-plugins (>= 1.0.0, < 2.0) 43 | cocoapods-search (>= 1.0.0, < 2.0) 44 | cocoapods-trunk (>= 1.6.0, < 2.0) 45 | cocoapods-try (>= 1.1.0, < 2.0) 46 | colored2 (~> 3.1) 47 | escape (~> 0.0.4) 48 | fourflusher (>= 2.3.0, < 3.0) 49 | gh_inspector (~> 1.0) 50 | molinillo (~> 0.8.0) 51 | nap (~> 1.0) 52 | ruby-macho (>= 2.3.0, < 3.0) 53 | xcodeproj (>= 1.21.0, < 2.0) 54 | cocoapods-core (1.12.0) 55 | activesupport (>= 5.0, < 8) 56 | addressable (~> 2.8) 57 | algoliasearch (~> 1.0) 58 | concurrent-ruby (~> 1.1) 59 | fuzzy_match (~> 2.0.4) 60 | nap (~> 1.0) 61 | netrc (~> 0.11) 62 | public_suffix (~> 4.0) 63 | typhoeus (~> 1.0) 64 | cocoapods-deintegrate (1.0.5) 65 | cocoapods-downloader (1.6.3) 66 | cocoapods-plugins (1.0.0) 67 | nap 68 | cocoapods-search (1.0.1) 69 | cocoapods-trunk (1.6.0) 70 | nap (>= 0.8, < 2.0) 71 | netrc (~> 0.11) 72 | cocoapods-try (1.2.0) 73 | colored (1.2) 74 | colored2 (3.1.2) 75 | commander (4.6.0) 76 | highline (~> 2.0.0) 77 | concurrent-ruby (1.2.2) 78 | declarative (0.0.20) 79 | digest-crc (0.6.5) 80 | rake (>= 12.0.0, < 14.0.0) 81 | domain_name (0.5.20190701) 82 | unf (>= 0.0.5, < 1.0.0) 83 | dotenv (2.8.1) 84 | emoji_regex (3.2.3) 85 | escape (0.0.4) 86 | ethon (0.15.0) 87 | ffi (>= 1.15.0) 88 | excon (0.103.0) 89 | faraday (1.10.3) 90 | faraday-em_http (~> 1.0) 91 | faraday-em_synchrony (~> 1.0) 92 | faraday-excon (~> 1.1) 93 | faraday-httpclient (~> 1.0) 94 | faraday-multipart (~> 1.0) 95 | faraday-net_http (~> 1.0) 96 | faraday-net_http_persistent (~> 1.0) 97 | faraday-patron (~> 1.0) 98 | faraday-rack (~> 1.0) 99 | faraday-retry (~> 1.0) 100 | ruby2_keywords (>= 0.0.4) 101 | faraday-cookie_jar (0.0.7) 102 | faraday (>= 0.8.0) 103 | http-cookie (~> 1.0.0) 104 | faraday-em_http (1.0.0) 105 | faraday-em_synchrony (1.0.0) 106 | faraday-excon (1.1.0) 107 | faraday-httpclient (1.0.1) 108 | faraday-multipart (1.0.4) 109 | multipart-post (~> 2) 110 | faraday-net_http (1.0.1) 111 | faraday-net_http_persistent (1.2.0) 112 | faraday-patron (1.0.0) 113 | faraday-rack (1.0.0) 114 | faraday-retry (1.0.3) 115 | faraday_middleware (1.2.0) 116 | faraday (~> 1.0) 117 | fastimage (2.2.7) 118 | fastlane (2.216.0) 119 | CFPropertyList (>= 2.3, < 4.0.0) 120 | addressable (>= 2.8, < 3.0.0) 121 | artifactory (~> 3.0) 122 | aws-sdk-s3 (~> 1.0) 123 | babosa (>= 1.0.3, < 2.0.0) 124 | bundler (>= 1.12.0, < 3.0.0) 125 | colored 126 | commander (~> 4.6) 127 | dotenv (>= 2.1.1, < 3.0.0) 128 | emoji_regex (>= 0.1, < 4.0) 129 | excon (>= 0.71.0, < 1.0.0) 130 | faraday (~> 1.0) 131 | faraday-cookie_jar (~> 0.0.6) 132 | faraday_middleware (~> 1.0) 133 | fastimage (>= 2.1.0, < 3.0.0) 134 | gh_inspector (>= 1.1.2, < 2.0.0) 135 | google-apis-androidpublisher_v3 (~> 0.3) 136 | google-apis-playcustomapp_v1 (~> 0.1) 137 | google-cloud-storage (~> 1.31) 138 | highline (~> 2.0) 139 | http-cookie (~> 1.0.5) 140 | json (< 3.0.0) 141 | jwt (>= 2.1.0, < 3) 142 | mini_magick (>= 4.9.4, < 5.0.0) 143 | multipart-post (>= 2.0.0, < 3.0.0) 144 | naturally (~> 2.2) 145 | optparse (~> 0.1.1) 146 | plist (>= 3.1.0, < 4.0.0) 147 | rubyzip (>= 2.0.0, < 3.0.0) 148 | security (= 0.1.3) 149 | simctl (~> 1.6.3) 150 | terminal-notifier (>= 2.0.0, < 3.0.0) 151 | terminal-table (~> 3) 152 | tty-screen (>= 0.6.3, < 1.0.0) 153 | tty-spinner (>= 0.8.0, < 1.0.0) 154 | word_wrap (~> 1.0.0) 155 | xcodeproj (>= 1.13.0, < 2.0.0) 156 | xcpretty (~> 0.3.0) 157 | xcpretty-travis-formatter (>= 0.0.3) 158 | ffi (1.15.5) 159 | fourflusher (2.3.1) 160 | fuzzy_match (2.0.4) 161 | gh_inspector (1.1.3) 162 | google-apis-androidpublisher_v3 (0.49.0) 163 | google-apis-core (>= 0.11.0, < 2.a) 164 | google-apis-core (0.11.1) 165 | addressable (~> 2.5, >= 2.5.1) 166 | googleauth (>= 0.16.2, < 2.a) 167 | httpclient (>= 2.8.1, < 3.a) 168 | mini_mime (~> 1.0) 169 | representable (~> 3.0) 170 | retriable (>= 2.0, < 4.a) 171 | rexml 172 | webrick 173 | google-apis-iamcredentials_v1 (0.17.0) 174 | google-apis-core (>= 0.11.0, < 2.a) 175 | google-apis-playcustomapp_v1 (0.13.0) 176 | google-apis-core (>= 0.11.0, < 2.a) 177 | google-apis-storage_v1 (0.19.0) 178 | google-apis-core (>= 0.9.0, < 2.a) 179 | google-cloud-core (1.6.0) 180 | google-cloud-env (~> 1.0) 181 | google-cloud-errors (~> 1.0) 182 | google-cloud-env (1.6.0) 183 | faraday (>= 0.17.3, < 3.0) 184 | google-cloud-errors (1.3.1) 185 | google-cloud-storage (1.44.0) 186 | addressable (~> 2.8) 187 | digest-crc (~> 0.4) 188 | google-apis-iamcredentials_v1 (~> 0.1) 189 | google-apis-storage_v1 (~> 0.19.0) 190 | google-cloud-core (~> 1.6) 191 | googleauth (>= 0.16.2, < 2.a) 192 | mini_mime (~> 1.0) 193 | googleauth (1.8.0) 194 | faraday (>= 0.17.3, < 3.a) 195 | jwt (>= 1.4, < 3.0) 196 | multi_json (~> 1.11) 197 | os (>= 0.9, < 2.0) 198 | signet (>= 0.16, < 2.a) 199 | highline (2.0.3) 200 | http-cookie (1.0.5) 201 | domain_name (~> 0.5) 202 | httpclient (2.8.3) 203 | i18n (1.10.0) 204 | concurrent-ruby (~> 1.0) 205 | jmespath (1.6.2) 206 | json (2.5.1) 207 | jwt (2.7.1) 208 | mini_magick (4.12.0) 209 | mini_mime (1.1.2) 210 | minitest (5.14.2) 211 | molinillo (0.8.0) 212 | multi_json (1.15.0) 213 | multipart-post (2.3.0) 214 | nanaimo (0.3.0) 215 | nap (1.1.0) 216 | naturally (2.2.1) 217 | netrc (0.11.0) 218 | optparse (0.1.1) 219 | os (1.1.4) 220 | plist (3.7.0) 221 | public_suffix (4.0.7) 222 | rake (13.0.3) 223 | representable (3.2.0) 224 | declarative (< 0.1.0) 225 | trailblazer-option (>= 0.1.1, < 0.2.0) 226 | uber (< 0.2.0) 227 | retriable (3.1.2) 228 | rexml (3.2.6) 229 | rouge (2.0.7) 230 | ruby-macho (2.5.1) 231 | ruby2_keywords (0.0.5) 232 | rubyzip (2.3.2) 233 | security (0.1.3) 234 | signet (0.18.0) 235 | addressable (~> 2.8) 236 | faraday (>= 0.17.5, < 3.a) 237 | jwt (>= 1.5, < 3.0) 238 | multi_json (~> 1.10) 239 | simctl (1.6.10) 240 | CFPropertyList 241 | naturally 242 | terminal-notifier (2.0.0) 243 | terminal-table (3.0.2) 244 | unicode-display_width (>= 1.1.1, < 3) 245 | trailblazer-option (0.1.2) 246 | tty-cursor (0.7.1) 247 | tty-screen (0.8.1) 248 | tty-spinner (0.9.3) 249 | tty-cursor (~> 0.7) 250 | typhoeus (1.4.0) 251 | ethon (>= 0.9.0) 252 | tzinfo (2.0.4) 253 | concurrent-ruby (~> 1.0) 254 | uber (0.1.0) 255 | unf (0.1.4) 256 | unf_ext 257 | unf_ext (0.0.8.2) 258 | unicode-display_width (2.4.2) 259 | webrick (1.8.1) 260 | word_wrap (1.0.0) 261 | xcodeproj (1.22.0) 262 | CFPropertyList (>= 2.3.3, < 4.0) 263 | atomos (~> 0.1.3) 264 | claide (>= 1.0.2, < 2.0) 265 | colored2 (~> 3.1) 266 | nanaimo (~> 0.3.0) 267 | rexml (~> 3.2.4) 268 | xcpretty (0.3.0) 269 | rouge (~> 2.0.7) 270 | xcpretty-travis-formatter (1.0.1) 271 | xcpretty (~> 0.2, >= 0.0.7) 272 | 273 | PLATFORMS 274 | arm64-darwin-21 275 | 276 | DEPENDENCIES 277 | cocoapods 278 | fastlane 279 | 280 | BUNDLED WITH 281 | 2.2.21 282 | -------------------------------------------------------------------------------- /EachNavigationBar/Classes/UIViewController+EachNavigationBar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+EachNavigationBar.swift 3 | // EachNavigationBar 4 | // 5 | // Created by Pircate(gao497868860@gmail.com) on 2018/3/26. 6 | // Copyright © 2018年 Pircate. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public extension UIViewController { 12 | 13 | func adjustsNavigationBarLayout() { 14 | _navigationBar.adjustsLayout() 15 | _navigationBar.setNeedsLayout() 16 | } 17 | 18 | @objc 19 | func adjustsNavigationBarConfiguration() { 20 | guard let navigationController = navigationController else { return } 21 | _navigationItem.update(navigationController._configuration) 22 | _navigationBar.update(navigationController._configuration) 23 | } 24 | } 25 | 26 | public extension UINavigationController { 27 | 28 | @objc 29 | override func adjustsNavigationBarConfiguration() { 30 | viewControllers.forEach { 31 | $0.adjustsNavigationBarConfiguration() 32 | } 33 | } 34 | } 35 | 36 | extension UIViewController { 37 | 38 | func setupNavigationBarWhenViewDidLoad() { 39 | guard let navigationController = navigationController else { return } 40 | 41 | navigationController.sendNavigationBarToBack() 42 | view.addSubview(_navigationBar) 43 | 44 | _navigationItem.apply(navigationController._configuration) 45 | _navigationBar.apply(navigationController._configuration) 46 | 47 | let viewControllers = navigationController.viewControllers 48 | 49 | guard viewControllers.count > 1 else { return } 50 | 51 | guard let backItem = navigationController._configuration.backItem else { 52 | _navigationBar.backBarButtonItem = buildBackBarButtonItem(viewControllers) 53 | return 54 | } 55 | 56 | _navigationBar.backBarButtonItem = BackBarButtonItem(from: backItem) 57 | } 58 | 59 | func updateNavigationBarWhenViewWillAppear() { 60 | guard let navigationBar = navigationController?.navigationBar else { return } 61 | navigationBar.barStyle = _navigationBar.superBarStyle 62 | navigationBar.isHidden = _navigationBar.isHidden 63 | adjustsSafeAreaInsets() 64 | navigationItem.title = _navigationItem.title 65 | navigationItem.largeTitleDisplayMode = _navigationItem.largeTitleDisplayMode 66 | navigationBar.prefersLargeTitles = _navigationBar.prefersLargeTitles 67 | navigationBar.largeTitleTextAttributes = _navigationBar.largeTitleTextAttributes 68 | view.bringSubviewToFront(_navigationBar) 69 | } 70 | 71 | func adjustsSafeAreaInsets() { 72 | let height = _navigationBar.additionalView?.frame.height ?? 0 73 | additionalSafeAreaInsets.top = _navigationBar.isHidden 74 | ? -view.safeAreaInsets.top 75 | : _navigationBar._additionalHeight + height 76 | } 77 | } 78 | 79 | private extension UIViewController { 80 | 81 | func buildBackBarButtonItem(_ viewControllers: [UIViewController]) -> BackBarButtonItem { 82 | let count = viewControllers.count 83 | 84 | let backButton = UIButton(type: .system) 85 | let image = UIImage(named: "navigation_back_default", in: Bundle.current, compatibleWith: nil) 86 | backButton.setImage(image, for: .normal) 87 | 88 | if let title = viewControllers[count - 2]._navigationItem.title { 89 | let maxWidth = min(UIScreen.main.bounds.width, UIScreen.main.bounds.height) / 3 90 | let width = (title as NSString).boundingRect( 91 | with: CGSize(width: maxWidth, height: 20), 92 | options: NSStringDrawingOptions.usesFontLeading, 93 | attributes: [.font: UIFont.boldSystemFont(ofSize: 17)], 94 | context: nil 95 | ).size.width 96 | backButton.setTitle(width < maxWidth ? title : "Back", for: .normal) 97 | } else { 98 | backButton.setTitle("Back", for: .normal) 99 | } 100 | backButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 17) 101 | backButton.contentEdgeInsets = .init(top: 0, left: -8, bottom: 0, right: 8) 102 | backButton.sizeToFit() 103 | 104 | return BackBarButtonItem(style: .custom(backButton)) 105 | } 106 | } 107 | 108 | private extension EachNavigationBar { 109 | 110 | func apply(_ configuration: UINavigationController.Configuration) { 111 | isHidden = configuration.isHidden 112 | alpha = configuration.alpha 113 | isTranslucent = configuration.isTranslucent 114 | barTintColor = configuration.barTintColor 115 | tintColor = configuration.tintColor 116 | 117 | titleTextAttributes = configuration.titleTextAttributes 118 | shadowImage = configuration.shadowImage 119 | setBackgroundImage( 120 | configuration.background.image, 121 | for: configuration.background.barPosition, 122 | barMetrics: configuration.background.barMetrics 123 | ) 124 | 125 | barStyle = configuration.barStyle 126 | statusBarStyle = configuration.statusBarStyle 127 | 128 | additionalHeight = configuration.additionalHeight 129 | 130 | isShadowHidden = configuration.isShadowHidden 131 | 132 | if let shadow = configuration.shadow { 133 | self.shadow = shadow 134 | } 135 | 136 | layoutPaddings = configuration.layoutPaddings 137 | prefersLargeTitles = configuration.prefersLargeTitles 138 | largeTitleTextAttributes = configuration.largeTitle.textAttributes 139 | 140 | // 清空修改记录 141 | changed.removeAll() 142 | } 143 | 144 | func update(_ configuration: UINavigationController.Configuration) { 145 | let original = changed 146 | 147 | if !changed.contains(\.isHidden) { 148 | isHidden = configuration.isHidden 149 | } 150 | if !changed.contains(\.alpha) { 151 | alpha = configuration.alpha 152 | } 153 | if !changed.contains(\.isTranslucent) { 154 | isTranslucent = configuration.isTranslucent 155 | } 156 | if !changed.contains(\.barTintColor) { 157 | barTintColor = configuration.barTintColor 158 | } 159 | if !changed.contains(\.tintColor) { 160 | tintColor = configuration.tintColor 161 | } 162 | if !changed.contains(\.titleTextAttributes) { 163 | titleTextAttributes = configuration.titleTextAttributes 164 | } 165 | if !changed.contains(\.shadowImage) { 166 | shadowImage = configuration.shadowImage 167 | } 168 | let backgroundImage = backgroundImage( 169 | for: configuration.background.barPosition, 170 | barMetrics: configuration.background.barMetrics 171 | ) 172 | if backgroundImage == nil { 173 | setBackgroundImage( 174 | configuration.background.image, 175 | for: configuration.background.barPosition, 176 | barMetrics: configuration.background.barMetrics 177 | ) 178 | } 179 | if !changed.contains(\.barStyle) { 180 | barStyle = configuration.barStyle 181 | } 182 | if !changed.contains(\.statusBarStyle) { 183 | statusBarStyle = configuration.statusBarStyle 184 | } 185 | if !changed.contains(\.additionalHeight) { 186 | additionalHeight = configuration.additionalHeight 187 | } 188 | if !changed.contains(\.isShadowHidden) { 189 | isShadowHidden = configuration.isShadowHidden 190 | } 191 | if !changed.contains(\.shadow) { 192 | if let shadow = configuration.shadow { 193 | self.shadow = shadow 194 | } 195 | } 196 | 197 | if !changed.contains(\.layoutPaddings) { 198 | layoutPaddings = configuration.layoutPaddings 199 | } 200 | if !changed.contains(\.prefersLargeTitles) { 201 | prefersLargeTitles = configuration.prefersLargeTitles 202 | } 203 | if !changed.contains(\.largeTitleTextAttributes) { 204 | largeTitleTextAttributes = configuration.largeTitle.textAttributes 205 | } 206 | 207 | // 恢复原始记录 208 | changed = original 209 | } 210 | } 211 | 212 | private extension EachNavigationItem { 213 | 214 | func apply(_ configuration: UINavigationController.Configuration) { 215 | largeTitleDisplayMode = configuration.largeTitle.displayMode 216 | 217 | // 清空修改记录 218 | changed.removeAll() 219 | } 220 | 221 | func update(_ configuration: UINavigationController.Configuration) { 222 | let original = changed 223 | 224 | if !changed.contains(\.largeTitleDisplayMode) { 225 | largeTitleDisplayMode = configuration.largeTitle.displayMode 226 | } 227 | 228 | // 恢复原始记录 229 | changed = original 230 | } 231 | } 232 | 233 | private extension Bundle { 234 | 235 | static var current: Bundle? { 236 | guard let resourcePath = Bundle(for: EachNavigationBar.self).resourcePath, 237 | let bundle = Bundle(path: "\(resourcePath)/EachNavigationBar.bundle") else { 238 | return nil 239 | } 240 | return bundle 241 | } 242 | } 243 | 244 | private extension BackBarButtonItem { 245 | 246 | convenience init(from backItem: UINavigationController.Configuration.BackItem) { 247 | switch backItem.style { 248 | case .title(let title): 249 | self.init(style: .title(title), tintColor: backItem.tintColor) 250 | case .image(let image): 251 | self.init(style: .image(image), tintColor: backItem.tintColor) 252 | } 253 | } 254 | } 255 | -------------------------------------------------------------------------------- /EachNavigationBar/Classes/EachNavigationBar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EachNavigationBar.swift 3 | // EachNavigationBar 4 | // 5 | // Created by Pircate(gao497868860@gmail.com) on 2018/3/28. 6 | // Copyright © 2018年 Pircate. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | open class EachNavigationBar: UINavigationBar { 12 | /// 记录修改过的属性 13 | var changed: Set> = [] 14 | 15 | /// automatically adjusts position when view layout 16 | open var automaticallyAdjustsPosition: Bool = true 17 | 18 | open override var barStyle: UIBarStyle { 19 | willSet { 20 | changed.insert(\.barStyle) 21 | } 22 | } 23 | 24 | /// Additional height for the navigation bar. 25 | open var additionalHeight: CGFloat = 0 { 26 | willSet { 27 | changed.insert(\.additionalHeight) 28 | } 29 | didSet { 30 | frame.size.height = barHeight + _additionalHeight 31 | viewController?.adjustsSafeAreaInsets() 32 | } 33 | } 34 | 35 | /// Hides shadow image 36 | open var isShadowHidden: Bool = false { 37 | willSet { 38 | changed.insert(\.isShadowHidden) 39 | } 40 | didSet { 41 | guard let background = subviews.first else { return } 42 | background.clipsToBounds = isShadowHidden 43 | } 44 | } 45 | 46 | open var statusBarStyle: UIStatusBarStyle = .default { 47 | willSet { 48 | changed.insert(\.statusBarStyle) 49 | } 50 | didSet { 51 | superNavigationBar?.barStyle = superBarStyle 52 | } 53 | } 54 | 55 | /// Bar button item to use for the back button in the child navigation item. 56 | open var backBarButtonItem: BackBarButtonItem? { 57 | willSet { 58 | changed.insert(\.backBarButtonItem) 59 | } 60 | didSet { 61 | backBarButtonItem?.navigationController = viewController?.navigationController 62 | 63 | viewController?._navigationItem.leftBarButtonItem = backBarButtonItem 64 | } 65 | } 66 | 67 | /// Padding of navigation bar content view. 68 | open var layoutPaddings: UIEdgeInsets { 69 | get { _layoutPaddings } 70 | set { 71 | _layoutPaddings = newValue 72 | changed.insert(\.layoutPaddings) 73 | } 74 | } 75 | 76 | /// Additional view at the bottom of the navigation bar 77 | open var additionalView: UIView? { 78 | didSet { 79 | guard let additionalView = additionalView else { 80 | oldValue?.removeFromSuperview() 81 | return 82 | } 83 | 84 | setupAdditionalView(additionalView) 85 | } 86 | } 87 | 88 | open var shadow: Shadow = .none { 89 | willSet { changed.insert(\.shadow) } 90 | didSet { layer.apply(shadow) } 91 | } 92 | 93 | private var appearance: UINavigationBarAppearance { 94 | if let _appearance = _appearance as? UINavigationBarAppearance { 95 | return _appearance 96 | } 97 | 98 | let appearance = UINavigationBarAppearance() 99 | 100 | appearance.backgroundColor = self.barTintColor 101 | appearance.titleTextAttributes = self.titleTextAttributes ?? [:] 102 | appearance.largeTitleTextAttributes = self.largeTitleTextAttributes ?? [:] 103 | 104 | _appearance = appearance 105 | 106 | return appearance 107 | } 108 | 109 | private var _appearance: Any? 110 | 111 | private var _alpha: CGFloat = 1 112 | 113 | private var _layoutPaddings: UIEdgeInsets = .barLayoutPaddings 114 | 115 | private var _contentView: UIView? 116 | 117 | private weak var viewController: UIViewController? 118 | 119 | public convenience init(viewController: UIViewController) { 120 | self.init() 121 | self.viewController = viewController 122 | setItems([viewController._navigationItem], animated: false) 123 | } 124 | 125 | open override func layoutSubviews() { 126 | super.layoutSubviews() 127 | 128 | _layoutSubviews() 129 | } 130 | } 131 | 132 | // MARK: - override 133 | extension EachNavigationBar { 134 | 135 | open override var isHidden: Bool { 136 | willSet { 137 | changed.insert(\.isHidden) 138 | } 139 | didSet { 140 | viewController?.adjustsSafeAreaInsets() 141 | } 142 | } 143 | 144 | open override var isTranslucent: Bool { 145 | willSet { 146 | changed.insert(\.isTranslucent) 147 | } 148 | didSet { 149 | guard !isTranslucent else { return } 150 | 151 | appearance.backgroundEffect = nil 152 | updateAppearance(appearance) 153 | } 154 | } 155 | 156 | open override var alpha: CGFloat { 157 | get { return super.alpha } 158 | set { 159 | _alpha = newValue 160 | 161 | layer.shadowOpacity = newValue < 1 ? 0 : shadow.opacity 162 | 163 | if let background = subviews.first { 164 | background.alpha = newValue 165 | } 166 | 167 | changed.insert(\.alpha) 168 | } 169 | } 170 | 171 | open override var tintColor: UIColor! { 172 | willSet { 173 | changed.insert(\.tintColor) 174 | } 175 | } 176 | 177 | open override var barTintColor: UIColor? { 178 | willSet { 179 | changed.insert(\.barTintColor) 180 | } 181 | didSet { 182 | appearance.backgroundColor = barTintColor 183 | updateAppearance(appearance) 184 | } 185 | } 186 | 187 | /// map to barTintColor 188 | open override var backgroundColor: UIColor? { 189 | get { return super.backgroundColor } 190 | set { barTintColor = newValue } 191 | } 192 | 193 | open override var shadowImage: UIImage? { 194 | willSet { 195 | changed.insert(\.shadowImage) 196 | } 197 | didSet { 198 | appearance.shadowImage = shadowImage 199 | updateAppearance(appearance) 200 | } 201 | } 202 | 203 | open override var titleTextAttributes: [NSAttributedString.Key: Any]? { 204 | willSet { 205 | changed.insert(\.titleTextAttributes) 206 | } 207 | didSet { 208 | appearance.titleTextAttributes = titleTextAttributes ?? [:] 209 | updateAppearance(appearance) 210 | } 211 | } 212 | 213 | open override var prefersLargeTitles: Bool { 214 | get { return super.prefersLargeTitles } 215 | set { 216 | super.prefersLargeTitles = newValue 217 | 218 | superNavigationBar?.prefersLargeTitles = newValue 219 | 220 | changed.insert(\.prefersLargeTitles) 221 | 222 | updateAppearance(appearance) 223 | } 224 | } 225 | 226 | open override var largeTitleTextAttributes: [NSAttributedString.Key: Any]? { 227 | get { return super.largeTitleTextAttributes } 228 | set { 229 | super.largeTitleTextAttributes = newValue 230 | 231 | viewController?.navigationItem.title = viewController?._navigationItem.title 232 | superNavigationBar?.largeTitleTextAttributes = newValue 233 | 234 | changed.insert(\.largeTitleTextAttributes) 235 | 236 | appearance.largeTitleTextAttributes = newValue ?? [:] 237 | updateAppearance(appearance) 238 | } 239 | } 240 | 241 | open override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { 242 | if super.point(inside: point, with: event) { return true } 243 | 244 | return additionalView?.frame.contains(point) ?? false 245 | } 246 | 247 | open override func setBackgroundImage( 248 | _ backgroundImage: UIImage?, 249 | for barPosition: UIBarPosition, 250 | barMetrics: UIBarMetrics 251 | ) { 252 | super.setBackgroundImage(backgroundImage, for: barPosition, barMetrics: barMetrics) 253 | 254 | appearance.backgroundImage = backgroundImage 255 | updateAppearance(appearance) 256 | } 257 | } 258 | 259 | extension EachNavigationBar { 260 | 261 | var superBarStyle: UIBarStyle { 262 | return statusBarStyle == .lightContent ? .black : .default 263 | } 264 | 265 | var _additionalHeight: CGFloat { 266 | guard !isLargeTitleShown else { 267 | return 0 268 | } 269 | 270 | return additionalHeight 271 | } 272 | 273 | var barMinY: CGFloat { 274 | let window = window ?? UIApplication.shared.windows.first { $0.isKeyWindow } 275 | 276 | return window?.safeAreaInsets.top ?? 0 277 | } 278 | 279 | func adjustsLayout() { 280 | guard let navigationBar = superNavigationBar else { return } 281 | 282 | if automaticallyAdjustsPosition { 283 | frame = navigationBar.frame 284 | frame.origin.y = barMinY 285 | } else { 286 | frame.size = navigationBar.frame.size 287 | } 288 | 289 | frame.size.height = navigationBar.frame.height + _additionalHeight 290 | } 291 | } 292 | 293 | // MARK: - private 294 | private extension EachNavigationBar { 295 | 296 | var superNavigationBar: UINavigationBar? { 297 | return viewController?.navigationController?.navigationBar 298 | } 299 | 300 | var contentView: UIView? { 301 | if let contentView = _contentView { return contentView } 302 | 303 | _contentView = subviews.first { 304 | String(describing: $0.classForCoder) == "_UINavigationBarContentView" 305 | } 306 | 307 | return _contentView 308 | } 309 | 310 | var isLargeTitleShown: Bool { 311 | return prefersLargeTitles && viewController?._navigationItem.largeTitleDisplayMode != .never 312 | } 313 | 314 | var barHeight: CGFloat { 315 | superNavigationBar?.frame.height ?? .navigationBarHeight 316 | } 317 | 318 | func _layoutSubviews() { 319 | guard let background = subviews.first else { return } 320 | background.alpha = _alpha 321 | background.clipsToBounds = isShadowHidden 322 | background.frame = CGRect( 323 | x: 0, 324 | y: -barMinY, 325 | width: bounds.width, 326 | height: bounds.height + barMinY 327 | ) 328 | 329 | adjustsLayoutMargins() 330 | } 331 | 332 | func adjustsLayoutMargins() { 333 | layoutMargins = .barLayoutMargins 334 | 335 | guard let contentView = contentView else { return } 336 | 337 | contentView.frame = CGRect( 338 | x: layoutPaddings.left - layoutMargins.left, 339 | y: isLargeTitleShown ? 0 : additionalHeight, 340 | width: layoutMargins.left 341 | + layoutMargins.right 342 | - layoutPaddings.left 343 | - layoutPaddings.right 344 | + contentView.frame.width, 345 | height: contentView.frame.height 346 | ) 347 | } 348 | 349 | func setupAdditionalView(_ additionalView: UIView) { 350 | addSubview(additionalView) 351 | additionalView.translatesAutoresizingMaskIntoConstraints = false 352 | NSLayoutConstraint.activate([ 353 | additionalView.topAnchor.constraint(equalTo: bottomAnchor), 354 | additionalView.leftAnchor.constraint(equalTo: leftAnchor), 355 | additionalView.widthAnchor.constraint(equalTo: widthAnchor), 356 | additionalView.heightAnchor.constraint(equalToConstant: additionalView.frame.height) 357 | ]) 358 | } 359 | 360 | func updateAppearance(_ appearance: UINavigationBarAppearance) { 361 | self.standardAppearance = appearance 362 | self.compactAppearance = appearance 363 | self.scrollEdgeAppearance = appearance 364 | } 365 | } 366 | -------------------------------------------------------------------------------- /Example/EachNavigationBar/MainViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 36 | 45 | 54 | 63 | 72 | 81 | 90 | 99 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | -------------------------------------------------------------------------------- /Example/EachNavigationBar.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; 11 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; 12 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; 13 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; 14 | 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; }; 15 | 6C005BCC2184380E009E8D0B /* TableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C005BCB2184380E009E8D0B /* TableViewController.swift */; }; 16 | 6CA615762181971600489F0F /* OCViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CA615752181971600489F0F /* OCViewController.m */; }; 17 | 6CFA46F821875FE000DF469C /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CFA46F621875FE000DF469C /* MainViewController.swift */; }; 18 | 6CFA46F921875FE000DF469C /* MainViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6CFA46F721875FE000DF469C /* MainViewController.xib */; }; 19 | AB5BABAB2F5290C4CE9E79CC /* Pods_EachNavigationBar_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 065403138A9FEECD97045A0D /* Pods_EachNavigationBar_Example.framework */; }; 20 | B50460F3208861EA00C47159 /* NextViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50460F2208861EA00C47159 /* NextViewController.swift */; }; 21 | E41841B893C1E012881AA63B /* Pods_EachNavigationBar_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB04741A356F0760ADD8B55F /* Pods_EachNavigationBar_Tests.framework */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXContainerItemProxy section */ 25 | 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */ = { 26 | isa = PBXContainerItemProxy; 27 | containerPortal = 607FACC81AFB9204008FA782 /* Project object */; 28 | proxyType = 1; 29 | remoteGlobalIDString = 607FACCF1AFB9204008FA782; 30 | remoteInfo = EachNavigationBar; 31 | }; 32 | /* End PBXContainerItemProxy section */ 33 | 34 | /* Begin PBXFileReference section */ 35 | 065403138A9FEECD97045A0D /* Pods_EachNavigationBar_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_EachNavigationBar_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 36 | 389D3AD49EDE388A3635EF2F /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; 37 | 607FACD01AFB9204008FA782 /* EachNavigationBar_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EachNavigationBar_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 39 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 40 | 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 41 | 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 42 | 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 43 | 607FACE51AFB9204008FA782 /* EachNavigationBar_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = EachNavigationBar_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 45 | 607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; 46 | 6C005BCB2184380E009E8D0B /* TableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewController.swift; sourceTree = ""; }; 47 | 6CA615732181971500489F0F /* EachNavigationBar_Example-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "EachNavigationBar_Example-Bridging-Header.h"; sourceTree = ""; }; 48 | 6CA615742181971600489F0F /* OCViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OCViewController.h; sourceTree = ""; }; 49 | 6CA615752181971600489F0F /* OCViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OCViewController.m; sourceTree = ""; }; 50 | 6CFA46F621875FE000DF469C /* MainViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = ""; }; 51 | 6CFA46F721875FE000DF469C /* MainViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainViewController.xib; sourceTree = ""; }; 52 | 7CCDC80169FB11DA20D877F8 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 53 | A117A3F435ACF9DE3690102A /* Pods-EachNavigationBar_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-EachNavigationBar_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-EachNavigationBar_Tests/Pods-EachNavigationBar_Tests.release.xcconfig"; sourceTree = ""; }; 54 | B50460F2208861EA00C47159 /* NextViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NextViewController.swift; sourceTree = ""; }; 55 | C088ADBF8B4C88FD6B82A889 /* Pods-EachNavigationBar_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-EachNavigationBar_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-EachNavigationBar_Example/Pods-EachNavigationBar_Example.release.xcconfig"; sourceTree = ""; }; 56 | C964FBED21DC84ED13CFEC3E /* Pods-EachNavigationBar_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-EachNavigationBar_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-EachNavigationBar_Tests/Pods-EachNavigationBar_Tests.debug.xcconfig"; sourceTree = ""; }; 57 | CCDF8E6E95979234BCE43BC2 /* EachNavigationBar.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = EachNavigationBar.podspec; path = ../EachNavigationBar.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 58 | DB04741A356F0760ADD8B55F /* Pods_EachNavigationBar_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_EachNavigationBar_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 59 | E8650B3C8219004704BFEEDE /* Pods-EachNavigationBar_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-EachNavigationBar_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-EachNavigationBar_Example/Pods-EachNavigationBar_Example.debug.xcconfig"; sourceTree = ""; }; 60 | /* End PBXFileReference section */ 61 | 62 | /* Begin PBXFrameworksBuildPhase section */ 63 | 607FACCD1AFB9204008FA782 /* Frameworks */ = { 64 | isa = PBXFrameworksBuildPhase; 65 | buildActionMask = 2147483647; 66 | files = ( 67 | AB5BABAB2F5290C4CE9E79CC /* Pods_EachNavigationBar_Example.framework in Frameworks */, 68 | ); 69 | runOnlyForDeploymentPostprocessing = 0; 70 | }; 71 | 607FACE21AFB9204008FA782 /* Frameworks */ = { 72 | isa = PBXFrameworksBuildPhase; 73 | buildActionMask = 2147483647; 74 | files = ( 75 | E41841B893C1E012881AA63B /* Pods_EachNavigationBar_Tests.framework in Frameworks */, 76 | ); 77 | runOnlyForDeploymentPostprocessing = 0; 78 | }; 79 | /* End PBXFrameworksBuildPhase section */ 80 | 81 | /* Begin PBXGroup section */ 82 | 607FACC71AFB9204008FA782 = { 83 | isa = PBXGroup; 84 | children = ( 85 | 607FACF51AFB993E008FA782 /* Podspec Metadata */, 86 | 607FACD21AFB9204008FA782 /* Example for EachNavigationBar */, 87 | 607FACE81AFB9204008FA782 /* Tests */, 88 | 607FACD11AFB9204008FA782 /* Products */, 89 | AF881A2063B4980D719509D9 /* Pods */, 90 | CF60BDBB3E50D21B345BE30F /* Frameworks */, 91 | ); 92 | sourceTree = ""; 93 | }; 94 | 607FACD11AFB9204008FA782 /* Products */ = { 95 | isa = PBXGroup; 96 | children = ( 97 | 607FACD01AFB9204008FA782 /* EachNavigationBar_Example.app */, 98 | 607FACE51AFB9204008FA782 /* EachNavigationBar_Tests.xctest */, 99 | ); 100 | name = Products; 101 | sourceTree = ""; 102 | }; 103 | 607FACD21AFB9204008FA782 /* Example for EachNavigationBar */ = { 104 | isa = PBXGroup; 105 | children = ( 106 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */, 107 | 6CFA46F621875FE000DF469C /* MainViewController.swift */, 108 | 6CFA46F721875FE000DF469C /* MainViewController.xib */, 109 | 607FACD71AFB9204008FA782 /* ViewController.swift */, 110 | B50460F2208861EA00C47159 /* NextViewController.swift */, 111 | 6C005BCB2184380E009E8D0B /* TableViewController.swift */, 112 | 6CA615742181971600489F0F /* OCViewController.h */, 113 | 6CA615752181971600489F0F /* OCViewController.m */, 114 | 607FACDC1AFB9204008FA782 /* Images.xcassets */, 115 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, 116 | 607FACD31AFB9204008FA782 /* Supporting Files */, 117 | 6CA615732181971500489F0F /* EachNavigationBar_Example-Bridging-Header.h */, 118 | ); 119 | name = "Example for EachNavigationBar"; 120 | path = EachNavigationBar; 121 | sourceTree = ""; 122 | }; 123 | 607FACD31AFB9204008FA782 /* Supporting Files */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | 607FACD41AFB9204008FA782 /* Info.plist */, 127 | ); 128 | name = "Supporting Files"; 129 | sourceTree = ""; 130 | }; 131 | 607FACE81AFB9204008FA782 /* Tests */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 607FACEB1AFB9204008FA782 /* Tests.swift */, 135 | 607FACE91AFB9204008FA782 /* Supporting Files */, 136 | ); 137 | path = Tests; 138 | sourceTree = ""; 139 | }; 140 | 607FACE91AFB9204008FA782 /* Supporting Files */ = { 141 | isa = PBXGroup; 142 | children = ( 143 | 607FACEA1AFB9204008FA782 /* Info.plist */, 144 | ); 145 | name = "Supporting Files"; 146 | sourceTree = ""; 147 | }; 148 | 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | CCDF8E6E95979234BCE43BC2 /* EachNavigationBar.podspec */, 152 | 7CCDC80169FB11DA20D877F8 /* README.md */, 153 | 389D3AD49EDE388A3635EF2F /* LICENSE */, 154 | ); 155 | name = "Podspec Metadata"; 156 | sourceTree = ""; 157 | }; 158 | AF881A2063B4980D719509D9 /* Pods */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | E8650B3C8219004704BFEEDE /* Pods-EachNavigationBar_Example.debug.xcconfig */, 162 | C088ADBF8B4C88FD6B82A889 /* Pods-EachNavigationBar_Example.release.xcconfig */, 163 | C964FBED21DC84ED13CFEC3E /* Pods-EachNavigationBar_Tests.debug.xcconfig */, 164 | A117A3F435ACF9DE3690102A /* Pods-EachNavigationBar_Tests.release.xcconfig */, 165 | ); 166 | name = Pods; 167 | sourceTree = ""; 168 | }; 169 | CF60BDBB3E50D21B345BE30F /* Frameworks */ = { 170 | isa = PBXGroup; 171 | children = ( 172 | 065403138A9FEECD97045A0D /* Pods_EachNavigationBar_Example.framework */, 173 | DB04741A356F0760ADD8B55F /* Pods_EachNavigationBar_Tests.framework */, 174 | ); 175 | name = Frameworks; 176 | sourceTree = ""; 177 | }; 178 | /* End PBXGroup section */ 179 | 180 | /* Begin PBXNativeTarget section */ 181 | 607FACCF1AFB9204008FA782 /* EachNavigationBar_Example */ = { 182 | isa = PBXNativeTarget; 183 | buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "EachNavigationBar_Example" */; 184 | buildPhases = ( 185 | 56B247BAC38286BC0C0CAB2C /* [CP] Check Pods Manifest.lock */, 186 | 607FACCC1AFB9204008FA782 /* Sources */, 187 | 607FACCD1AFB9204008FA782 /* Frameworks */, 188 | 607FACCE1AFB9204008FA782 /* Resources */, 189 | 17B1E448E8ED39ECD6CE7D73 /* [CP] Embed Pods Frameworks */, 190 | ); 191 | buildRules = ( 192 | ); 193 | dependencies = ( 194 | ); 195 | name = EachNavigationBar_Example; 196 | productName = EachNavigationBar; 197 | productReference = 607FACD01AFB9204008FA782 /* EachNavigationBar_Example.app */; 198 | productType = "com.apple.product-type.application"; 199 | }; 200 | 607FACE41AFB9204008FA782 /* EachNavigationBar_Tests */ = { 201 | isa = PBXNativeTarget; 202 | buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "EachNavigationBar_Tests" */; 203 | buildPhases = ( 204 | D79DD291938FB2823CEA273D /* [CP] Check Pods Manifest.lock */, 205 | 607FACE11AFB9204008FA782 /* Sources */, 206 | 607FACE21AFB9204008FA782 /* Frameworks */, 207 | 607FACE31AFB9204008FA782 /* Resources */, 208 | ); 209 | buildRules = ( 210 | ); 211 | dependencies = ( 212 | 607FACE71AFB9204008FA782 /* PBXTargetDependency */, 213 | ); 214 | name = EachNavigationBar_Tests; 215 | productName = Tests; 216 | productReference = 607FACE51AFB9204008FA782 /* EachNavigationBar_Tests.xctest */; 217 | productType = "com.apple.product-type.bundle.unit-test"; 218 | }; 219 | /* End PBXNativeTarget section */ 220 | 221 | /* Begin PBXProject section */ 222 | 607FACC81AFB9204008FA782 /* Project object */ = { 223 | isa = PBXProject; 224 | attributes = { 225 | LastSwiftUpdateCheck = 0830; 226 | LastUpgradeCheck = 1020; 227 | ORGANIZATIONNAME = CocoaPods; 228 | TargetAttributes = { 229 | 607FACCF1AFB9204008FA782 = { 230 | CreatedOnToolsVersion = 6.3.1; 231 | DevelopmentTeam = 8G74YECJ4Z; 232 | LastSwiftMigration = 1020; 233 | }; 234 | 607FACE41AFB9204008FA782 = { 235 | CreatedOnToolsVersion = 6.3.1; 236 | LastSwiftMigration = 1020; 237 | TestTargetID = 607FACCF1AFB9204008FA782; 238 | }; 239 | }; 240 | }; 241 | buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "EachNavigationBar" */; 242 | compatibilityVersion = "Xcode 3.2"; 243 | developmentRegion = en; 244 | hasScannedForEncodings = 0; 245 | knownRegions = ( 246 | en, 247 | Base, 248 | ); 249 | mainGroup = 607FACC71AFB9204008FA782; 250 | productRefGroup = 607FACD11AFB9204008FA782 /* Products */; 251 | projectDirPath = ""; 252 | projectRoot = ""; 253 | targets = ( 254 | 607FACCF1AFB9204008FA782 /* EachNavigationBar_Example */, 255 | 607FACE41AFB9204008FA782 /* EachNavigationBar_Tests */, 256 | ); 257 | }; 258 | /* End PBXProject section */ 259 | 260 | /* Begin PBXResourcesBuildPhase section */ 261 | 607FACCE1AFB9204008FA782 /* Resources */ = { 262 | isa = PBXResourcesBuildPhase; 263 | buildActionMask = 2147483647; 264 | files = ( 265 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */, 266 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */, 267 | 6CFA46F921875FE000DF469C /* MainViewController.xib in Resources */, 268 | ); 269 | runOnlyForDeploymentPostprocessing = 0; 270 | }; 271 | 607FACE31AFB9204008FA782 /* Resources */ = { 272 | isa = PBXResourcesBuildPhase; 273 | buildActionMask = 2147483647; 274 | files = ( 275 | ); 276 | runOnlyForDeploymentPostprocessing = 0; 277 | }; 278 | /* End PBXResourcesBuildPhase section */ 279 | 280 | /* Begin PBXShellScriptBuildPhase section */ 281 | 17B1E448E8ED39ECD6CE7D73 /* [CP] Embed Pods Frameworks */ = { 282 | isa = PBXShellScriptBuildPhase; 283 | buildActionMask = 2147483647; 284 | files = ( 285 | ); 286 | inputPaths = ( 287 | ); 288 | name = "[CP] Embed Pods Frameworks"; 289 | outputPaths = ( 290 | ); 291 | runOnlyForDeploymentPostprocessing = 0; 292 | shellPath = /bin/sh; 293 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-EachNavigationBar_Example/Pods-EachNavigationBar_Example-frameworks.sh\"\n"; 294 | showEnvVarsInLog = 0; 295 | }; 296 | 56B247BAC38286BC0C0CAB2C /* [CP] Check Pods Manifest.lock */ = { 297 | isa = PBXShellScriptBuildPhase; 298 | buildActionMask = 2147483647; 299 | files = ( 300 | ); 301 | inputPaths = ( 302 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 303 | "${PODS_ROOT}/Manifest.lock", 304 | ); 305 | name = "[CP] Check Pods Manifest.lock"; 306 | outputPaths = ( 307 | "$(DERIVED_FILE_DIR)/Pods-EachNavigationBar_Example-checkManifestLockResult.txt", 308 | ); 309 | runOnlyForDeploymentPostprocessing = 0; 310 | shellPath = /bin/sh; 311 | 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"; 312 | showEnvVarsInLog = 0; 313 | }; 314 | D79DD291938FB2823CEA273D /* [CP] Check Pods Manifest.lock */ = { 315 | isa = PBXShellScriptBuildPhase; 316 | buildActionMask = 2147483647; 317 | files = ( 318 | ); 319 | inputPaths = ( 320 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 321 | "${PODS_ROOT}/Manifest.lock", 322 | ); 323 | name = "[CP] Check Pods Manifest.lock"; 324 | outputPaths = ( 325 | "$(DERIVED_FILE_DIR)/Pods-EachNavigationBar_Tests-checkManifestLockResult.txt", 326 | ); 327 | runOnlyForDeploymentPostprocessing = 0; 328 | shellPath = /bin/sh; 329 | 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"; 330 | showEnvVarsInLog = 0; 331 | }; 332 | /* End PBXShellScriptBuildPhase section */ 333 | 334 | /* Begin PBXSourcesBuildPhase section */ 335 | 607FACCC1AFB9204008FA782 /* Sources */ = { 336 | isa = PBXSourcesBuildPhase; 337 | buildActionMask = 2147483647; 338 | files = ( 339 | 6CFA46F821875FE000DF469C /* MainViewController.swift in Sources */, 340 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */, 341 | B50460F3208861EA00C47159 /* NextViewController.swift in Sources */, 342 | 6CA615762181971600489F0F /* OCViewController.m in Sources */, 343 | 6C005BCC2184380E009E8D0B /* TableViewController.swift in Sources */, 344 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, 345 | ); 346 | runOnlyForDeploymentPostprocessing = 0; 347 | }; 348 | 607FACE11AFB9204008FA782 /* Sources */ = { 349 | isa = PBXSourcesBuildPhase; 350 | buildActionMask = 2147483647; 351 | files = ( 352 | 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */, 353 | ); 354 | runOnlyForDeploymentPostprocessing = 0; 355 | }; 356 | /* End PBXSourcesBuildPhase section */ 357 | 358 | /* Begin PBXTargetDependency section */ 359 | 607FACE71AFB9204008FA782 /* PBXTargetDependency */ = { 360 | isa = PBXTargetDependency; 361 | target = 607FACCF1AFB9204008FA782 /* EachNavigationBar_Example */; 362 | targetProxy = 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */; 363 | }; 364 | /* End PBXTargetDependency section */ 365 | 366 | /* Begin PBXVariantGroup section */ 367 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = { 368 | isa = PBXVariantGroup; 369 | children = ( 370 | 607FACDF1AFB9204008FA782 /* Base */, 371 | ); 372 | name = LaunchScreen.xib; 373 | sourceTree = ""; 374 | }; 375 | /* End PBXVariantGroup section */ 376 | 377 | /* Begin XCBuildConfiguration section */ 378 | 607FACED1AFB9204008FA782 /* Debug */ = { 379 | isa = XCBuildConfiguration; 380 | buildSettings = { 381 | ALWAYS_SEARCH_USER_PATHS = NO; 382 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 383 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 384 | CLANG_CXX_LIBRARY = "libc++"; 385 | CLANG_ENABLE_MODULES = YES; 386 | CLANG_ENABLE_OBJC_ARC = YES; 387 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 388 | CLANG_WARN_BOOL_CONVERSION = YES; 389 | CLANG_WARN_COMMA = YES; 390 | CLANG_WARN_CONSTANT_CONVERSION = YES; 391 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 392 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 393 | CLANG_WARN_EMPTY_BODY = YES; 394 | CLANG_WARN_ENUM_CONVERSION = YES; 395 | CLANG_WARN_INFINITE_RECURSION = YES; 396 | CLANG_WARN_INT_CONVERSION = YES; 397 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 398 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 399 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 400 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 401 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 402 | CLANG_WARN_STRICT_PROTOTYPES = YES; 403 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 404 | CLANG_WARN_UNREACHABLE_CODE = YES; 405 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 406 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 407 | COPY_PHASE_STRIP = NO; 408 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 409 | ENABLE_STRICT_OBJC_MSGSEND = YES; 410 | ENABLE_TESTABILITY = YES; 411 | GCC_C_LANGUAGE_STANDARD = gnu99; 412 | GCC_DYNAMIC_NO_PIC = NO; 413 | GCC_NO_COMMON_BLOCKS = YES; 414 | GCC_OPTIMIZATION_LEVEL = 0; 415 | GCC_PREPROCESSOR_DEFINITIONS = ( 416 | "DEBUG=1", 417 | "$(inherited)", 418 | ); 419 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 420 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 421 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 422 | GCC_WARN_UNDECLARED_SELECTOR = YES; 423 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 424 | GCC_WARN_UNUSED_FUNCTION = YES; 425 | GCC_WARN_UNUSED_VARIABLE = YES; 426 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 427 | MTL_ENABLE_DEBUG_INFO = YES; 428 | ONLY_ACTIVE_ARCH = YES; 429 | SDKROOT = iphoneos; 430 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 431 | }; 432 | name = Debug; 433 | }; 434 | 607FACEE1AFB9204008FA782 /* Release */ = { 435 | isa = XCBuildConfiguration; 436 | buildSettings = { 437 | ALWAYS_SEARCH_USER_PATHS = NO; 438 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 439 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 440 | CLANG_CXX_LIBRARY = "libc++"; 441 | CLANG_ENABLE_MODULES = YES; 442 | CLANG_ENABLE_OBJC_ARC = YES; 443 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 444 | CLANG_WARN_BOOL_CONVERSION = YES; 445 | CLANG_WARN_COMMA = YES; 446 | CLANG_WARN_CONSTANT_CONVERSION = YES; 447 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 448 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 449 | CLANG_WARN_EMPTY_BODY = YES; 450 | CLANG_WARN_ENUM_CONVERSION = YES; 451 | CLANG_WARN_INFINITE_RECURSION = YES; 452 | CLANG_WARN_INT_CONVERSION = YES; 453 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 454 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 455 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 456 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 457 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 458 | CLANG_WARN_STRICT_PROTOTYPES = YES; 459 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 460 | CLANG_WARN_UNREACHABLE_CODE = YES; 461 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 462 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 463 | COPY_PHASE_STRIP = NO; 464 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 465 | ENABLE_NS_ASSERTIONS = NO; 466 | ENABLE_STRICT_OBJC_MSGSEND = YES; 467 | GCC_C_LANGUAGE_STANDARD = gnu99; 468 | GCC_NO_COMMON_BLOCKS = YES; 469 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 470 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 471 | GCC_WARN_UNDECLARED_SELECTOR = YES; 472 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 473 | GCC_WARN_UNUSED_FUNCTION = YES; 474 | GCC_WARN_UNUSED_VARIABLE = YES; 475 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 476 | MTL_ENABLE_DEBUG_INFO = NO; 477 | SDKROOT = iphoneos; 478 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 479 | VALIDATE_PRODUCT = YES; 480 | }; 481 | name = Release; 482 | }; 483 | 607FACF01AFB9204008FA782 /* Debug */ = { 484 | isa = XCBuildConfiguration; 485 | baseConfigurationReference = E8650B3C8219004704BFEEDE /* Pods-EachNavigationBar_Example.debug.xcconfig */; 486 | buildSettings = { 487 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 488 | CLANG_ENABLE_MODULES = YES; 489 | DEVELOPMENT_TEAM = 8G74YECJ4Z; 490 | INFOPLIST_FILE = EachNavigationBar/Info.plist; 491 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 492 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 493 | MODULE_NAME = ExampleApp; 494 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; 495 | PRODUCT_NAME = "$(TARGET_NAME)"; 496 | SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/EachNavigationBar/EachNavigationBar_Example-Bridging-Header.h"; 497 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 498 | SWIFT_VERSION = 5.0; 499 | }; 500 | name = Debug; 501 | }; 502 | 607FACF11AFB9204008FA782 /* Release */ = { 503 | isa = XCBuildConfiguration; 504 | baseConfigurationReference = C088ADBF8B4C88FD6B82A889 /* Pods-EachNavigationBar_Example.release.xcconfig */; 505 | buildSettings = { 506 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 507 | CLANG_ENABLE_MODULES = YES; 508 | DEVELOPMENT_TEAM = 8G74YECJ4Z; 509 | INFOPLIST_FILE = EachNavigationBar/Info.plist; 510 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 511 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 512 | MODULE_NAME = ExampleApp; 513 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; 514 | PRODUCT_NAME = "$(TARGET_NAME)"; 515 | SWIFT_OBJC_BRIDGING_HEADER = "$(SRCROOT)/EachNavigationBar/EachNavigationBar_Example-Bridging-Header.h"; 516 | SWIFT_VERSION = 5.0; 517 | }; 518 | name = Release; 519 | }; 520 | 607FACF31AFB9204008FA782 /* Debug */ = { 521 | isa = XCBuildConfiguration; 522 | baseConfigurationReference = C964FBED21DC84ED13CFEC3E /* Pods-EachNavigationBar_Tests.debug.xcconfig */; 523 | buildSettings = { 524 | FRAMEWORK_SEARCH_PATHS = "$(inherited)"; 525 | GCC_PREPROCESSOR_DEFINITIONS = ( 526 | "DEBUG=1", 527 | "$(inherited)", 528 | ); 529 | INFOPLIST_FILE = Tests/Info.plist; 530 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 531 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; 532 | PRODUCT_NAME = "$(TARGET_NAME)"; 533 | SWIFT_VERSION = 5.0; 534 | }; 535 | name = Debug; 536 | }; 537 | 607FACF41AFB9204008FA782 /* Release */ = { 538 | isa = XCBuildConfiguration; 539 | baseConfigurationReference = A117A3F435ACF9DE3690102A /* Pods-EachNavigationBar_Tests.release.xcconfig */; 540 | buildSettings = { 541 | FRAMEWORK_SEARCH_PATHS = "$(inherited)"; 542 | INFOPLIST_FILE = Tests/Info.plist; 543 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 544 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; 545 | PRODUCT_NAME = "$(TARGET_NAME)"; 546 | SWIFT_VERSION = 5.0; 547 | }; 548 | name = Release; 549 | }; 550 | /* End XCBuildConfiguration section */ 551 | 552 | /* Begin XCConfigurationList section */ 553 | 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "EachNavigationBar" */ = { 554 | isa = XCConfigurationList; 555 | buildConfigurations = ( 556 | 607FACED1AFB9204008FA782 /* Debug */, 557 | 607FACEE1AFB9204008FA782 /* Release */, 558 | ); 559 | defaultConfigurationIsVisible = 0; 560 | defaultConfigurationName = Release; 561 | }; 562 | 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "EachNavigationBar_Example" */ = { 563 | isa = XCConfigurationList; 564 | buildConfigurations = ( 565 | 607FACF01AFB9204008FA782 /* Debug */, 566 | 607FACF11AFB9204008FA782 /* Release */, 567 | ); 568 | defaultConfigurationIsVisible = 0; 569 | defaultConfigurationName = Release; 570 | }; 571 | 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "EachNavigationBar_Tests" */ = { 572 | isa = XCConfigurationList; 573 | buildConfigurations = ( 574 | 607FACF31AFB9204008FA782 /* Debug */, 575 | 607FACF41AFB9204008FA782 /* Release */, 576 | ); 577 | defaultConfigurationIsVisible = 0; 578 | defaultConfigurationName = Release; 579 | }; 580 | /* End XCConfigurationList section */ 581 | }; 582 | rootObject = 607FACC81AFB9204008FA782 /* Project object */; 583 | } 584 | --------------------------------------------------------------------------------