├── 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 | [](https://github.com/Pircate/EachNavigationBar/actions?query=workflow%3ALint)
4 | [](http://cocoapods.org/pods/EachNavigationBar)
5 | [](https://github.com/Carthage/Carthage)
6 | [](http://cocoapods.org/pods/EachNavigationBar)
7 | [](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 | 
36 | 
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 | [](https://github.com/Pircate/EachNavigationBar/actions?query=workflow%3ALint)
4 | [](http://cocoapods.org/pods/EachNavigationBar)
5 | [](https://github.com/Carthage/Carthage)
6 | [](http://cocoapods.org/pods/EachNavigationBar)
7 | [](https://cocoapods.org/pods/EachNavigationBar)
8 | [](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 | 
40 | 
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 |
--------------------------------------------------------------------------------