├── .gitignore
├── .gitattributes
├── ZXNavigationBarDemo
├── ZXNavigationBarDemo
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ ├── nav_bac.imageset
│ │ │ ├── nav_bac.png
│ │ │ └── Contents.json
│ │ ├── set_icon.imageset
│ │ │ ├── set_icon2.png
│ │ │ └── Contents.json
│ │ ├── light_icon.imageset
│ │ │ ├── light_icon.png
│ │ │ └── Contents.json
│ │ ├── search_icon.imageset
│ │ │ ├── search_icon.png
│ │ │ └── Contents.json
│ │ ├── recycle_icon.imageset
│ │ │ ├── recycle_icon.png
│ │ │ └── Contents.json
│ │ ├── weibo_hot_bac.imageset
│ │ │ ├── weibo_hot_bac.jpg
│ │ │ └── Contents.json
│ │ ├── right_more_icon.imageset
│ │ │ ├── right_more_icon.png
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── ZXNavigationBar
│ │ ├── ZXNavigationBar.bundle
│ │ │ └── back_icon.png
│ │ ├── ZXNavigationBarSubViews
│ │ │ ├── ZXNavBacImageView.m
│ │ │ ├── ZXNavHistoryStackView
│ │ │ │ ├── Model
│ │ │ │ │ ├── ZXNavHistoryStackModel.m
│ │ │ │ │ └── ZXNavHistoryStackModel.h
│ │ │ │ └── View
│ │ │ │ │ ├── ZXNavHistoryStackView.h
│ │ │ │ │ ├── ZXNavHistoryStackCell.h
│ │ │ │ │ ├── ZXNavHistoryStackView.m
│ │ │ │ │ ├── ZXNavHistoryStackContentView.h
│ │ │ │ │ ├── ZXNavHistoryStackCell.m
│ │ │ │ │ └── ZXNavHistoryStackContentView.m
│ │ │ ├── ZXNavTitleView.h
│ │ │ ├── ZXNavBacImageView.h
│ │ │ ├── ZXNavTitleLabel.h
│ │ │ ├── ZXNavTitleView.m
│ │ │ ├── ZXNavTitleLabel.m
│ │ │ └── ZXNavItemBtn.h
│ │ ├── ZXNavigationBarHelper
│ │ │ └── ZXNavigationBarCategory
│ │ │ │ ├── UIImage+ZXNavBundleExtension.h
│ │ │ │ ├── UIImage+ZXNavColorRender.h
│ │ │ │ ├── NSString+ZXNavCalcSizeExtension.h
│ │ │ │ ├── NSAttributedString+ZXNavCalcSizeExtension.h
│ │ │ │ ├── ZXNavigationBarController+ZXNavSystemBarPopHandle.h
│ │ │ │ ├── UINavigationController+ZXNavBarAllHiddenExtension.h
│ │ │ │ ├── UIView+ZXNavFrameExtension.h
│ │ │ │ ├── UIImage+ZXNavBundleExtension.m
│ │ │ │ ├── NSAttributedString+ZXNavCalcSizeExtension.m
│ │ │ │ ├── UIImage+ZXNavColorRender.m
│ │ │ │ ├── NSString+ZXNavCalcSizeExtension.m
│ │ │ │ ├── UINavigationController+ZXNavBarAllHiddenExtension.m
│ │ │ │ ├── ZXNavigationBarController+ZXNavSystemBarPopHandle.m
│ │ │ │ └── UIView+ZXNavFrameExtension.m
│ │ ├── ZXNavigationBarNavigationController.h
│ │ ├── ZXNavigationBar.h
│ │ ├── ZXNavigationBarDefine.h
│ │ └── ZXNavigationBarNavigationController.m
│ ├── AppDelegate.h
│ ├── Demo
│ │ ├── DemoCustomNavViewController
│ │ │ ├── DemoCustomNav
│ │ │ │ ├── DemoCustomNav.h
│ │ │ │ ├── DemoCustomNav.m
│ │ │ │ └── DemoCustomNav.xib
│ │ │ ├── DemoCustomNavViewController.h
│ │ │ └── DemoCustomNavViewController.m
│ │ ├── DemoCustomTitleViewViewController
│ │ │ ├── DemoCustomTitleView
│ │ │ │ ├── DemoCustomTitleView.h
│ │ │ │ ├── DemoCustomTitleView.m
│ │ │ │ └── DemoCustomTitleView.xib
│ │ │ ├── DemoCustomTitleViewViewController.h
│ │ │ └── DemoCustomTitleViewViewController.m
│ │ ├── DemoBaseViewController
│ │ │ ├── DemoBaseViewController.h
│ │ │ └── DemoBaseViewController.m
│ │ ├── DemoListViewController
│ │ │ ├── DemoListViewController.h
│ │ │ └── DemoListViewController.m
│ │ ├── DemoXibViewController
│ │ │ ├── DemoXibViewController.h
│ │ │ └── DemoXibViewController.m
│ │ ├── DemoFoldXibViewController
│ │ │ ├── DemoFoldXibViewController.h
│ │ │ ├── DemoFoldXibViewController.xib
│ │ │ └── DemoFoldXibViewController.m
│ │ ├── DemoWeiboHotViewController
│ │ │ ├── DemoWeiboHotViewController.h
│ │ │ └── DemoWeiboHotViewController.m
│ │ ├── DemoFoldFrameViewController
│ │ │ ├── DemoFoldFrameViewController.h
│ │ │ └── DemoFoldFrameViewController.m
│ │ ├── DemoSystemBarViewController
│ │ │ ├── DemoPublicSystemBarViewController.h
│ │ │ ├── DemoSystemBarViewController.h
│ │ │ ├── DemoSystemBarViewController.m
│ │ │ └── DemoPublicSystemBarViewController.m
│ │ └── DemoCompatibleScrollViewViewController
│ │ │ ├── DemoCompatibleScrollViewViewController.h
│ │ │ └── DemoCompatibleScrollViewViewController.m
│ ├── main.m
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── Info.plist
│ └── AppDelegate.m
├── ZXNavigationBarDemo.xcodeproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcuserdata
│ │ │ ├── lzx.xcuserdatad
│ │ │ │ └── UserInterfaceState.xcuserstate
│ │ │ └── mac.xcuserdatad
│ │ │ │ └── UserInterfaceState.xcuserstate
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── xcuserdata
│ │ ├── lzx.xcuserdatad
│ │ ├── xcschemes
│ │ │ └── xcschememanagement.plist
│ │ └── xcdebugger
│ │ │ └── Breakpoints_v2.xcbkptlist
│ │ └── mac.xcuserdatad
│ │ ├── xcschemes
│ │ └── xcschememanagement.plist
│ │ └── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
└── ZXNavigationBarDemoUITests
│ ├── Info.plist
│ └── ZXNavigationBarDemoUITests.m
├── ZXNavigationBar
├── ZXNavigationBar.bundle
│ └── back_icon.png
├── ZXNavigationBarSubViews
│ ├── ZXNavBacImageView.m
│ ├── ZXNavHistoryStackView
│ │ ├── Model
│ │ │ ├── ZXNavHistoryStackModel.m
│ │ │ └── ZXNavHistoryStackModel.h
│ │ └── View
│ │ │ ├── ZXNavHistoryStackView.h
│ │ │ ├── ZXNavHistoryStackCell.h
│ │ │ ├── ZXNavHistoryStackView.m
│ │ │ ├── ZXNavHistoryStackContentView.h
│ │ │ ├── ZXNavHistoryStackCell.m
│ │ │ └── ZXNavHistoryStackContentView.m
│ ├── ZXNavTitleView.h
│ ├── ZXNavBacImageView.h
│ ├── ZXNavTitleLabel.h
│ ├── ZXNavTitleView.m
│ ├── ZXNavTitleLabel.m
│ ├── ZXNavItemBtn.h
│ └── ZXNavItemBtn.m
├── ZXNavigationBarHelper
│ └── ZXNavigationBarCategory
│ │ ├── UIImage+ZXNavBundleExtension.h
│ │ ├── UIImage+ZXNavColorRender.h
│ │ ├── NSString+ZXNavCalcSizeExtension.h
│ │ ├── NSAttributedString+ZXNavCalcSizeExtension.h
│ │ ├── ZXNavigationBarController+ZXNavSystemBarPopHandle.h
│ │ ├── UINavigationController+ZXNavBarAllHiddenExtension.h
│ │ ├── UIView+ZXNavFrameExtension.h
│ │ ├── UIImage+ZXNavBundleExtension.m
│ │ ├── NSAttributedString+ZXNavCalcSizeExtension.m
│ │ ├── UIImage+ZXNavColorRender.m
│ │ ├── NSString+ZXNavCalcSizeExtension.m
│ │ ├── UINavigationController+ZXNavBarAllHiddenExtension.m
│ │ ├── ZXNavigationBarController+ZXNavSystemBarPopHandle.m
│ │ └── UIView+ZXNavFrameExtension.m
├── ZXNavigationBarNavigationController.h
├── ZXNavigationBar.h
├── ZXNavigationBarDefine.h
└── ZXNavigationBarNavigationController.m
├── ZXNavigationBar.podspec
└── LICENSE
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | Thumbs.db
3 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBar.bundle/back_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmileZXLee/ZXNavigationBar/HEAD/ZXNavigationBar/ZXNavigationBar.bundle/back_icon.png
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Assets.xcassets/nav_bac.imageset/nav_bac.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmileZXLee/ZXNavigationBar/HEAD/ZXNavigationBarDemo/ZXNavigationBarDemo/Assets.xcassets/nav_bac.imageset/nav_bac.png
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Assets.xcassets/set_icon.imageset/set_icon2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmileZXLee/ZXNavigationBar/HEAD/ZXNavigationBarDemo/ZXNavigationBarDemo/Assets.xcassets/set_icon.imageset/set_icon2.png
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Assets.xcassets/light_icon.imageset/light_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmileZXLee/ZXNavigationBar/HEAD/ZXNavigationBarDemo/ZXNavigationBarDemo/Assets.xcassets/light_icon.imageset/light_icon.png
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Assets.xcassets/search_icon.imageset/search_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmileZXLee/ZXNavigationBar/HEAD/ZXNavigationBarDemo/ZXNavigationBarDemo/Assets.xcassets/search_icon.imageset/search_icon.png
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBar.bundle/back_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmileZXLee/ZXNavigationBar/HEAD/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBar.bundle/back_icon.png
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Assets.xcassets/recycle_icon.imageset/recycle_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmileZXLee/ZXNavigationBar/HEAD/ZXNavigationBarDemo/ZXNavigationBarDemo/Assets.xcassets/recycle_icon.imageset/recycle_icon.png
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Assets.xcassets/weibo_hot_bac.imageset/weibo_hot_bac.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmileZXLee/ZXNavigationBar/HEAD/ZXNavigationBarDemo/ZXNavigationBarDemo/Assets.xcassets/weibo_hot_bac.imageset/weibo_hot_bac.jpg
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Assets.xcassets/right_more_icon.imageset/right_more_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmileZXLee/ZXNavigationBar/HEAD/ZXNavigationBarDemo/ZXNavigationBarDemo/Assets.xcassets/right_more_icon.imageset/right_more_icon.png
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo.xcodeproj/project.xcworkspace/xcuserdata/lzx.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmileZXLee/ZXNavigationBar/HEAD/ZXNavigationBarDemo/ZXNavigationBarDemo.xcodeproj/project.xcworkspace/xcuserdata/lzx.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo.xcodeproj/project.xcworkspace/xcuserdata/mac.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmileZXLee/ZXNavigationBar/HEAD/ZXNavigationBarDemo/ZXNavigationBarDemo.xcodeproj/project.xcworkspace/xcuserdata/mac.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavBacImageView.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavBacImageView.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/10.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "ZXNavBacImageView.h"
11 |
12 | @implementation ZXNavBacImageView
13 |
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/7.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoCustomNavViewController/DemoCustomNav/DemoCustomNav.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoCustomNav.h
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/12.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface DemoCustomNav : UIView
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavBacImageView.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavBacImageView.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/10.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "ZXNavBacImageView.h"
11 |
12 | @implementation ZXNavBacImageView
13 |
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavHistoryStackView/Model/ZXNavHistoryStackModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavHistoryStackModel.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/12/22.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "ZXNavHistoryStackModel.h"
11 |
12 | @implementation ZXNavHistoryStackModel
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavTitleView.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavTitleView.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/12.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface ZXNavTitleView : UIView
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/7.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavBacImageView.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavBacImageView.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/10.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface ZXNavBacImageView : UIImageView
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoCustomTitleViewViewController/DemoCustomTitleView/DemoCustomTitleView.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoCustomTitleView.h
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/12.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface DemoCustomTitleView : UIView
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoBaseViewController/DemoBaseViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoBaseViewController.h
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/10.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import "ZXNavigationBarController.h"
10 | NS_ASSUME_NONNULL_BEGIN
11 |
12 | @interface DemoBaseViewController : ZXNavigationBarController
13 |
14 | @end
15 |
16 | NS_ASSUME_NONNULL_END
17 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoListViewController/DemoListViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoListViewController.h
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/10.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import "DemoBaseViewController.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface DemoListViewController : DemoBaseViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoXibViewController/DemoXibViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoXibViewController.h
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/10.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import "DemoBaseViewController.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface DemoXibViewController : ZXNavigationBarController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoFoldXibViewController/DemoFoldXibViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoFoldXibViewController.h
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/13.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import "DemoBaseViewController.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface DemoFoldXibViewController : DemoBaseViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoWeiboHotViewController/DemoWeiboHotViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoWeiboHotViewController.h
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/12.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import "DemoBaseViewController.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface DemoWeiboHotViewController : DemoBaseViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavHistoryStackView/Model/ZXNavHistoryStackModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavHistoryStackModel.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/12/22.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "ZXNavHistoryStackModel.h"
11 |
12 | @implementation ZXNavHistoryStackModel
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Assets.xcassets/nav_bac.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "nav_bac.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoCustomNavViewController/DemoCustomNavViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoCustomNavViewController.h
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/12.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import "DemoBaseViewController.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface DemoCustomNavViewController : DemoBaseViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoFoldFrameViewController/DemoFoldFrameViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoTelescopicViewController.h
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/13.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import "DemoBaseViewController.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface DemoFoldFrameViewController : DemoBaseViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoSystemBarViewController/DemoPublicSystemBarViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoPublicSystemBarViewController.h
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/8/4.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface DemoPublicSystemBarViewController : UIViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavTitleView.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavTitleView.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/12.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface ZXNavTitleView : UIView
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Assets.xcassets/light_icon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "light_icon.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Assets.xcassets/set_icon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "set_icon2.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Assets.xcassets/recycle_icon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "recycle_icon.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Assets.xcassets/search_icon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "search_icon.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Assets.xcassets/weibo_hot_bac.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "weibo_hot_bac.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Assets.xcassets/right_more_icon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "right_more_icon.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavBacImageView.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavBacImageView.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/10.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface ZXNavBacImageView : UIImageView
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavHistoryStackView/View/ZXNavHistoryStackView.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavHistoryStackView.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/12/22.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface ZXNavHistoryStackView : UICollectionView
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoCustomTitleViewViewController/DemoCustomTitleViewViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoCustomTitleViewViewController.h
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/12.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import "DemoBaseViewController.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface DemoCustomTitleViewViewController : DemoBaseViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoSystemBarViewController/DemoSystemBarViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoSystemBarViewController.h
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/11.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "DemoBaseViewController.h"
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface DemoSystemBarViewController : DemoBaseViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo.xcodeproj/xcuserdata/lzx.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ZXNavigationBarDemo.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo.xcodeproj/xcuserdata/mac.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ZXNavigationBarDemo.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoCompatibleScrollViewViewController/DemoCompatibleScrollViewViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoCompatibleScrollViewViewController.h
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/7/29.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import "DemoBaseViewController.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface DemoCompatibleScrollViewViewController : DemoBaseViewController
14 |
15 | @end
16 |
17 | NS_ASSUME_NONNULL_END
18 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavHistoryStackView/View/ZXNavHistoryStackView.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavHistoryStackView.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/12/22.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface ZXNavHistoryStackView : UICollectionView
15 |
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/UIImage+ZXNavBundleExtension.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+ZXNavBundleExtension.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/11.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface UIImage (ZXNavBundleExtension)
15 | + (UIImage *)zx_imageFromBundleWithImageName:(NSString *)imageName;
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavTitleLabel.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavTitleLabel.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/7.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface ZXNavTitleLabel : UILabel
15 | //NavTitleLabel的frame更新回调
16 | @property (copy, nonatomic) void (^zx_titleLabelFrameUpdateBlock)(ZXNavTitleLabel *titleLabel);
17 | @end
18 |
19 | NS_ASSUME_NONNULL_END
20 |
--------------------------------------------------------------------------------
/ZXNavigationBar.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'ZXNavigationBar'
3 | s.version = '1.4.1'
4 | s.summary = '灵活轻量的自定义导航栏,轻松实现各种自定义效果'
5 | s.homepage = 'https://github.com/SmileZXLee/ZXNavigationBar'
6 | s.license = 'MIT'
7 | s.authors = {'李兆祥' => '393727164@qq.com'}
8 | s.platform = :ios, '8.0'
9 | s.source = {:git => 'https://github.com/SmileZXLee/ZXNavigationBar.git', :tag => s.version}
10 | s.source_files = 'ZXNavigationBar/**/*.{h,m}'
11 | s.resource = 'ZXNavigationBar/ZXNavigationBar.bundle'
12 | s.requires_arc = true
13 | end
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoCustomNavViewController/DemoCustomNav/DemoCustomNav.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoCustomNav.m
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/12.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import "DemoCustomNav.h"
10 |
11 | @implementation DemoCustomNav
12 |
13 | /*
14 | // Only override drawRect: if you perform custom drawing.
15 | // An empty implementation adversely affects performance during animation.
16 | - (void)drawRect:(CGRect)rect {
17 | // Drawing code
18 | }
19 | */
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavTitleView.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavTitleView.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/12.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "ZXNavTitleView.h"
11 |
12 | @implementation ZXNavTitleView
13 |
14 | /*
15 | // Only override drawRect: if you perform custom drawing.
16 | // An empty implementation adversely affects performance during animation.
17 | - (void)drawRect:(CGRect)rect {
18 | // Drawing code
19 | }
20 | */
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/UIImage+ZXNavBundleExtension.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+ZXNavBundleExtension.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/11.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface UIImage (ZXNavBundleExtension)
15 | + (UIImage *)zx_imageFromBundleWithImageName:(NSString *)imageName;
16 | @end
17 |
18 | NS_ASSUME_NONNULL_END
19 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavTitleLabel.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavTitleLabel.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/7.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface ZXNavTitleLabel : UILabel
15 | //NavTitleLabel的frame更新回调
16 | @property (copy, nonatomic) void (^zx_titleLabelFrameUpdateBlock)(ZXNavTitleLabel *titleLabel);
17 | @end
18 |
19 | NS_ASSUME_NONNULL_END
20 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/UIImage+ZXNavColorRender.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+ZXNavColorRender.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/10.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface UIImage (ZXNavColorRender)
15 |
16 | /**
17 | 图片渲染
18 |
19 | @param color 需要渲染的颜色
20 | @return 渲染后的图片
21 | */
22 | - (UIImage *)zx_renderingColor:(UIColor *)color;
23 | @end
24 |
25 | NS_ASSUME_NONNULL_END
26 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavTitleView.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavTitleView.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/12.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "ZXNavTitleView.h"
11 |
12 | @implementation ZXNavTitleView
13 |
14 | /*
15 | // Only override drawRect: if you perform custom drawing.
16 | // An empty implementation adversely affects performance during animation.
17 | - (void)drawRect:(CGRect)rect {
18 | // Drawing code
19 | }
20 | */
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/UIImage+ZXNavColorRender.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+ZXNavColorRender.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/10.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface UIImage (ZXNavColorRender)
15 |
16 | /**
17 | 图片渲染
18 |
19 | @param color 需要渲染的颜色
20 | @return 渲染后的图片
21 | */
22 | - (UIImage *)zx_renderingColor:(UIColor *)color;
23 | @end
24 |
25 | NS_ASSUME_NONNULL_END
26 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavHistoryStackView/View/ZXNavHistoryStackCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavHistoryStackCell.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/12/22.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 | #import "ZXNavHistoryStackModel.h"
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface ZXNavHistoryStackCell : UICollectionViewCell
15 | @property (strong, nonatomic) ZXNavHistoryStackModel *historyStackModel;
16 | @property (assign, nonatomic) ZXNavHistoryStackViewStyle historyStackViewStyle;
17 | @end
18 |
19 | NS_ASSUME_NONNULL_END
20 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/NSString+ZXNavCalcSizeExtension.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+ZXNavCalcSizeExtension.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/7.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 | #import
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface NSString (ZXNavCalcSizeExtension)
15 | - (CGFloat)zx_getRectHeightWithLimitW:(CGFloat)limitW fontSize:(CGFloat)fontSize;
16 | - (CGFloat)zx_getRectWidthWithLimitH:(CGFloat)limitH fontSize:(CGFloat)fontSize;
17 | @end
18 |
19 | NS_ASSUME_NONNULL_END
20 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoBaseViewController/DemoBaseViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoBaseViewController.m
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/10.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import "DemoBaseViewController.h"
10 |
11 | @interface DemoBaseViewController ()
12 |
13 | @end
14 |
15 | @implementation DemoBaseViewController
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 | self.zx_navStatusBarStyle = ZXNavStatusBarStyleDefault;
20 | self.zx_showNavHistoryStackContentView = YES;
21 | }
22 |
23 | - (void)dealloc{
24 | NSLog(@"%@-dealloc",[self class]);
25 | }
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoCustomTitleViewViewController/DemoCustomTitleView/DemoCustomTitleView.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoCustomTitleView.m
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/12.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import "DemoCustomTitleView.h"
10 | @interface DemoCustomTitleView()
11 | @property (weak, nonatomic) IBOutlet UIView *titleView;
12 |
13 | @end
14 | @implementation DemoCustomTitleView
15 |
16 | - (void)layoutSubviews{
17 | [super layoutSubviews];
18 | self.titleView.layer.cornerRadius = self.titleView.frame.size.height / 2;
19 | self.titleView.clipsToBounds = YES;
20 | }
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavHistoryStackView/View/ZXNavHistoryStackCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavHistoryStackCell.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/12/22.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 | #import "ZXNavHistoryStackModel.h"
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface ZXNavHistoryStackCell : UICollectionViewCell
15 | @property (strong, nonatomic) ZXNavHistoryStackModel *historyStackModel;
16 | @property (assign, nonatomic) ZXNavHistoryStackViewStyle historyStackViewStyle;
17 | @end
18 |
19 | NS_ASSUME_NONNULL_END
20 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/NSString+ZXNavCalcSizeExtension.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+ZXNavCalcSizeExtension.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/7.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 | #import
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface NSString (ZXNavCalcSizeExtension)
15 | - (CGFloat)zx_getRectHeightWithLimitW:(CGFloat)limitW fontSize:(CGFloat)fontSize;
16 | - (CGFloat)zx_getRectWidthWithLimitH:(CGFloat)limitH fontSize:(CGFloat)fontSize;
17 | @end
18 |
19 | NS_ASSUME_NONNULL_END
20 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/NSAttributedString+ZXNavCalcSizeExtension.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSAttributedString+ZXNavCalcSizeExtension.h
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/10/23.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 | #import
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface NSAttributedString (ZXNavCalcSizeExtension)
15 | - (CGFloat)zx_getAttrRectWidthWithLimitH:(CGFloat)limitH fontSize:(CGFloat)fontSize;
16 | - (CGFloat)zx_getAttrRectHeightWithLimitW:(CGFloat)limitW fontSize:(CGFloat)fontSize;
17 | @end
18 |
19 | NS_ASSUME_NONNULL_END
20 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavHistoryStackView/View/ZXNavHistoryStackView.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavHistoryStackView.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/12/22.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "ZXNavHistoryStackView.h"
11 |
12 | @implementation ZXNavHistoryStackView
13 |
14 | #pragma mark - Init
15 | - (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(nonnull UICollectionViewLayout *)layout{
16 | self = [super initWithFrame:frame collectionViewLayout:layout];
17 | if(self){
18 | [self setUp];
19 | }
20 | return self;
21 | }
22 |
23 | - (void)setUp{
24 |
25 | }
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/NSAttributedString+ZXNavCalcSizeExtension.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSAttributedString+ZXNavCalcSizeExtension.h
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/10/23.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 | #import
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface NSAttributedString (ZXNavCalcSizeExtension)
15 | - (CGFloat)zx_getAttrRectWidthWithLimitH:(CGFloat)limitH fontSize:(CGFloat)fontSize;
16 | - (CGFloat)zx_getAttrRectHeightWithLimitW:(CGFloat)limitW fontSize:(CGFloat)fontSize;
17 | @end
18 |
19 | NS_ASSUME_NONNULL_END
20 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/ZXNavigationBarController+ZXNavSystemBarPopHandle.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavigationBarController+ZXNavSystemBarPopHandle.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/5/29.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | //Thanks to @onegray https://github.com/onegray/UIViewController-BackButtonHandler Respect!
11 |
12 | #import "ZXNavigationBarController.h"
13 |
14 | NS_ASSUME_NONNULL_BEGIN
15 | @protocol ZXBackButtonHandlerProtocol
16 | @optional
17 |
18 | -(BOOL)zx_navSystemBarPopHandle;
19 | @end
20 | @interface UIViewController (ZXNavSystemBarPopHandle)
21 |
22 | @end
23 |
24 | NS_ASSUME_NONNULL_END
25 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavHistoryStackView/View/ZXNavHistoryStackView.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavHistoryStackView.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/12/22.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "ZXNavHistoryStackView.h"
11 |
12 | @implementation ZXNavHistoryStackView
13 |
14 | #pragma mark - Init
15 | - (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(nonnull UICollectionViewLayout *)layout{
16 | self = [super initWithFrame:frame collectionViewLayout:layout];
17 | if(self){
18 | [self setUp];
19 | }
20 | return self;
21 | }
22 |
23 | - (void)setUp{
24 |
25 | }
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo.xcodeproj/xcuserdata/lzx.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
9 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo.xcodeproj/xcuserdata/mac.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
9 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/UINavigationController+ZXNavBarAllHiddenExtension.h:
--------------------------------------------------------------------------------
1 | //
2 | // UINavigationController+ZXNavBarAllHiddenExtension.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/20.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface UINavigationController (ZXNavBarAllHiddenExtension)
15 |
16 | /**
17 | 隐藏所有导航栏【可有效避免可能出现的状态栏颜色黑白切换或导航栏跳动的问题】(请在appdelegate的didFinishLaunchingWithOptions中设置,并确保在根控制器初始化之前,若导航控制器为ZXNavigationBarNavigationController或其子控制器,无需进行此项设置)
18 | */
19 | + (void)zx_hideAllNavBar;
20 |
21 | /**
22 | 取消隐藏所有导航栏
23 | */
24 | + (void)zx_removeAllNavBar;
25 | @end
26 |
27 | NS_ASSUME_NONNULL_END
28 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/ZXNavigationBarController+ZXNavSystemBarPopHandle.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavigationBarController+ZXNavSystemBarPopHandle.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/5/29.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | //Thanks to @onegray https://github.com/onegray/UIViewController-BackButtonHandler Respect!
11 |
12 | #import "ZXNavigationBarController.h"
13 |
14 | NS_ASSUME_NONNULL_BEGIN
15 | @protocol ZXBackButtonHandlerProtocol
16 | @optional
17 |
18 | -(BOOL)zx_navSystemBarPopHandle;
19 | @end
20 | @interface UIViewController (ZXNavSystemBarPopHandle)
21 |
22 | @end
23 |
24 | NS_ASSUME_NONNULL_END
25 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemoUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
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 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoSystemBarViewController/DemoSystemBarViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoSystemBarViewController.m
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/11.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import "DemoSystemBarViewController.h"
10 |
11 | @implementation DemoSystemBarViewController
12 | - (void)viewDidLoad {
13 | [super viewDidLoad];
14 | self.title = @"系统导航栏(继承于ZXNavigationBarController)";
15 | self.zx_showSystemNavBar = YES;
16 | self.view.backgroundColor = [UIColor whiteColor];
17 |
18 | UILabel *label = [[UILabel alloc]init];
19 | label.frame = CGRectMake(0, 10, ZXScreenWidth, 20);
20 | label.textAlignment = NSTextAlignmentCenter;
21 | label.text = @"这是一个系统导航栏的控制器";
22 | [self.view addSubview:label];
23 |
24 | }
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/UINavigationController+ZXNavBarAllHiddenExtension.h:
--------------------------------------------------------------------------------
1 | //
2 | // UINavigationController+ZXNavBarAllHiddenExtension.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/20.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface UINavigationController (ZXNavBarAllHiddenExtension)
15 |
16 | /**
17 | 隐藏所有导航栏【可有效避免可能出现的状态栏颜色黑白切换或导航栏跳动的问题】(请在appdelegate的didFinishLaunchingWithOptions中设置,并确保在根控制器初始化之前,若导航控制器为ZXNavigationBarNavigationController或其子控制器,无需进行此项设置)
18 | */
19 | + (void)zx_hideAllNavBar;
20 |
21 | /**
22 | 取消隐藏所有导航栏
23 | */
24 | + (void)zx_removeAllNavBar;
25 | @end
26 |
27 | NS_ASSUME_NONNULL_END
28 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavHistoryStackView/Model/ZXNavHistoryStackModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavHistoryStackModel.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/12/22.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 | #import
12 | typedef enum {
13 | ZXNavHistoryStackViewStyleLight = 0x00, // 历史堆栈浅色模式
14 | ZXNavHistoryStackViewStyleDark = 0x01, // 历史堆栈深色模式
15 | }ZXNavHistoryStackViewStyle;
16 | NS_ASSUME_NONNULL_BEGIN
17 |
18 | @interface ZXNavHistoryStackModel : NSObject
19 | @property (copy, nonatomic) NSString *title;
20 | @property (strong, nonatomic) UIViewController *viewController;
21 | @property (assign, nonatomic) BOOL isSelected;
22 | @property (assign, nonatomic) BOOL isLast;
23 | @end
24 |
25 | NS_ASSUME_NONNULL_END
26 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/UIView+ZXNavFrameExtension.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+ZXNavFrameExtension.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/7.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.3.6
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface UIView (ZXNavFrameExtension)
15 | @property (nonatomic) CGFloat zx_x;
16 | @property (nonatomic) CGFloat zx_y;
17 | @property (nonatomic) CGFloat zx_width;
18 | @property (nonatomic) CGFloat zx_height;
19 | @property (nonatomic) CGFloat zx_right;
20 | @property (nonatomic) CGFloat zx_bottom;
21 | @property (nonatomic) CGFloat zx_centerX;
22 | @property (nonatomic) CGFloat zx_centerY;
23 | @property (nonatomic) CGPoint zx_origin;
24 | @property (nonatomic) CGSize zx_size;
25 | @end
26 |
27 | NS_ASSUME_NONNULL_END
28 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavTitleLabel.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavTitleLabel.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/7.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "ZXNavTitleLabel.h"
11 |
12 | @implementation ZXNavTitleLabel
13 |
14 | - (void)setText:(NSString *)text{
15 | [super setText:text];
16 | [self noticeUpdateFrame];
17 | }
18 |
19 | - (void)setAttributedText:(NSAttributedString *)attributedText{
20 | [super setAttributedText:attributedText];
21 | [self noticeUpdateFrame];
22 | }
23 |
24 | - (void)setFont:(UIFont *)font{
25 | [super setFont:font];
26 | [self noticeUpdateFrame];
27 | }
28 |
29 | - (void)noticeUpdateFrame{
30 | if(self.zx_titleLabelFrameUpdateBlock){
31 | self.zx_titleLabelFrameUpdateBlock(self);
32 | }
33 | }
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavHistoryStackView/Model/ZXNavHistoryStackModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavHistoryStackModel.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/12/22.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 | #import
12 | typedef enum {
13 | ZXNavHistoryStackViewStyleLight = 0x00, // 历史堆栈浅色模式
14 | ZXNavHistoryStackViewStyleDark = 0x01, // 历史堆栈深色模式
15 | }ZXNavHistoryStackViewStyle;
16 | NS_ASSUME_NONNULL_BEGIN
17 |
18 | @interface ZXNavHistoryStackModel : NSObject
19 | @property (copy, nonatomic) NSString *title;
20 | @property (strong, nonatomic) UIViewController *viewController;
21 | @property (assign, nonatomic) BOOL isSelected;
22 | @property (assign, nonatomic) BOOL isLast;
23 | @end
24 |
25 | NS_ASSUME_NONNULL_END
26 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/UIView+ZXNavFrameExtension.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+ZXNavFrameExtension.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/7.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.3.6
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface UIView (ZXNavFrameExtension)
15 | @property (nonatomic) CGFloat zx_x;
16 | @property (nonatomic) CGFloat zx_y;
17 | @property (nonatomic) CGFloat zx_width;
18 | @property (nonatomic) CGFloat zx_height;
19 | @property (nonatomic) CGFloat zx_right;
20 | @property (nonatomic) CGFloat zx_bottom;
21 | @property (nonatomic) CGFloat zx_centerX;
22 | @property (nonatomic) CGFloat zx_centerY;
23 | @property (nonatomic) CGPoint zx_origin;
24 | @property (nonatomic) CGSize zx_size;
25 | @end
26 |
27 | NS_ASSUME_NONNULL_END
28 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavTitleLabel.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavTitleLabel.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/7.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "ZXNavTitleLabel.h"
11 |
12 | @implementation ZXNavTitleLabel
13 |
14 | - (void)setText:(NSString *)text{
15 | [super setText:text];
16 | [self noticeUpdateFrame];
17 | }
18 |
19 | - (void)setAttributedText:(NSAttributedString *)attributedText{
20 | [super setAttributedText:attributedText];
21 | [self noticeUpdateFrame];
22 | }
23 |
24 | - (void)setFont:(UIFont *)font{
25 | [super setFont:font];
26 | [self noticeUpdateFrame];
27 | }
28 |
29 | - (void)noticeUpdateFrame{
30 | if(self.zx_titleLabelFrameUpdateBlock){
31 | self.zx_titleLabelFrameUpdateBlock(self);
32 | }
33 | }
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/UIImage+ZXNavBundleExtension.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+ZXNavBundleExtension.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/11.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "UIImage+ZXNavBundleExtension.h"
11 | #import "ZXNavigationBar.h"
12 | @implementation UIImage (ZXNavBundleExtension)
13 |
14 | + (UIImage *)zx_imageFromBundleWithImageName:(NSString *)imageName{
15 | static UIImage *image = nil;
16 | if (image == nil) {
17 | NSBundle *bundle = [NSBundle bundleWithPath:[[NSBundle bundleForClass:[ZXNavigationBar class]] pathForResource:@"ZXNavigationBar" ofType:@"bundle"]];
18 | image = [[UIImage imageWithContentsOfFile:[bundle pathForResource:imageName ofType:@"png"]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
19 | }
20 | return image;
21 | }
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/UIImage+ZXNavBundleExtension.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+ZXNavBundleExtension.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/11.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "UIImage+ZXNavBundleExtension.h"
11 | #import "ZXNavigationBar.h"
12 | @implementation UIImage (ZXNavBundleExtension)
13 |
14 | + (UIImage *)zx_imageFromBundleWithImageName:(NSString *)imageName{
15 | static UIImage *image = nil;
16 | if (image == nil) {
17 | NSBundle *bundle = [NSBundle bundleWithPath:[[NSBundle bundleForClass:[ZXNavigationBar class]] pathForResource:@"ZXNavigationBar" ofType:@"bundle"]];
18 | image = [[UIImage imageWithContentsOfFile:[bundle pathForResource:imageName ofType:@"png"]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
19 | }
20 | return image;
21 | }
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavHistoryStackView/View/ZXNavHistoryStackContentView.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavHistoryStackContentView.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/12/22.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 | #import "ZXNavHistoryStackView.h"
12 | #import "ZXNavHistoryStackModel.h"
13 | NS_ASSUME_NONNULL_BEGIN
14 |
15 |
16 | @interface ZXNavHistoryStackContentView : UIView
17 | @property (strong, nonatomic) ZXNavHistoryStackView *zx_historyStackView;
18 | @property (strong, nonatomic) NSMutableArray *zx_historyStackArray;
19 | ///导航栏历史堆栈视图与屏幕左侧的距离,与返回按钮与屏幕左侧的距离相同,交由内部处理,修改此属性无效
20 | @property (assign, nonatomic) CGFloat zx_historyStackViewLeft;
21 | ///导航栏历史堆栈视图显示样式
22 | @property (assign, nonatomic) ZXNavHistoryStackViewStyle zx_historyStackViewStyle;
23 | - (instancetype)zx_show;
24 | - (void)zx_hide;
25 | @end
26 |
27 | NS_ASSUME_NONNULL_END
28 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoCustomTitleViewViewController/DemoCustomTitleViewViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoCustomTitleViewViewController.m
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/12.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import "DemoCustomTitleViewViewController.h"
10 | #import "DemoCustomTitleView.h"
11 | @implementation DemoCustomTitleViewViewController
12 | - (void)viewDidLoad {
13 | [super viewDidLoad];
14 | [self setUpNav];
15 | [self setUpView];
16 | }
17 |
18 | - (void)setUpNav{
19 | DemoCustomTitleView *customTitleView = [[[NSBundle mainBundle]loadNibNamed:NSStringFromClass([DemoCustomTitleView class]) owner:nil options:nil]lastObject];
20 | [self zx_addCustomTitleView:customTitleView];
21 |
22 | [self zx_setRightBtnWithText:@"测试" clickedBlock:^(ZXNavItemBtn * _Nonnull btn) {
23 |
24 | }];
25 | }
26 |
27 | - (void)setUpView{
28 | self.view.backgroundColor = [UIColor whiteColor];
29 | }
30 | @end
31 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavHistoryStackView/View/ZXNavHistoryStackContentView.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavHistoryStackContentView.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/12/22.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 | #import "ZXNavHistoryStackView.h"
12 | #import "ZXNavHistoryStackModel.h"
13 | NS_ASSUME_NONNULL_BEGIN
14 |
15 |
16 | @interface ZXNavHistoryStackContentView : UIView
17 | @property (strong, nonatomic) ZXNavHistoryStackView *zx_historyStackView;
18 | @property (strong, nonatomic) NSMutableArray *zx_historyStackArray;
19 | ///导航栏历史堆栈视图与屏幕左侧的距离,与返回按钮与屏幕左侧的距离相同,交由内部处理,修改此属性无效
20 | @property (assign, nonatomic) CGFloat zx_historyStackViewLeft;
21 | ///导航栏历史堆栈视图显示样式
22 | @property (assign, nonatomic) ZXNavHistoryStackViewStyle zx_historyStackViewStyle;
23 | - (instancetype)zx_show;
24 | - (void)zx_hide;
25 | @end
26 |
27 | NS_ASSUME_NONNULL_END
28 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/NSAttributedString+ZXNavCalcSizeExtension.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSAttributedString+ZXNavCalcSizeExtension.m
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/10/23.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "NSAttributedString+ZXNavCalcSizeExtension.h"
11 |
12 | @implementation NSAttributedString (ZXNavCalcSizeExtension)
13 | - (CGFloat)zx_getAttrRectWidthWithLimitH:(CGFloat)limitH fontSize:(CGFloat)fontSize{
14 | UILabel *label = [[UILabel alloc]init];
15 | label.font = [UIFont systemFontOfSize:fontSize];
16 | label.attributedText = self;
17 | return [label sizeThatFits:CGSizeMake(MAXFLOAT, limitH)].width;
18 | }
19 | - (CGFloat)zx_getAttrRectHeightWithLimitW:(CGFloat)limitW fontSize:(CGFloat)fontSize{
20 | UILabel *label = [[UILabel alloc]init];
21 | label.font = [UIFont systemFontOfSize:fontSize];
22 | label.attributedText = self;
23 | return [label sizeThatFits:CGSizeMake(limitW,MAXFLOAT )].height;
24 | }
25 | @end
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 李兆祥
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/UIImage+ZXNavColorRender.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+ZXNavColorRender.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/10.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "UIImage+ZXNavColorRender.h"
11 |
12 | @implementation UIImage (ZXNavColorRender)
13 | - (UIImage *)zx_renderingColor:(UIColor *)color{
14 | UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
15 | CGContextRef context = UIGraphicsGetCurrentContext();
16 | CGContextTranslateCTM(context, 0, self.size.height);
17 | CGContextScaleCTM(context, 1.0, -1.0);
18 | CGContextSetBlendMode(context, kCGBlendModeNormal);
19 | CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
20 | CGContextClipToMask(context, rect, self.CGImage);
21 | [color setFill];
22 | CGContextFillRect(context, rect);
23 | UIImage *renderedImage = UIGraphicsGetImageFromCurrentImageContext();
24 | UIGraphicsEndImageContext();
25 | return renderedImage;
26 | }
27 | @end
28 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/NSAttributedString+ZXNavCalcSizeExtension.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSAttributedString+ZXNavCalcSizeExtension.m
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/10/23.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "NSAttributedString+ZXNavCalcSizeExtension.h"
11 |
12 | @implementation NSAttributedString (ZXNavCalcSizeExtension)
13 | - (CGFloat)zx_getAttrRectWidthWithLimitH:(CGFloat)limitH fontSize:(CGFloat)fontSize{
14 | UILabel *label = [[UILabel alloc]init];
15 | label.font = [UIFont systemFontOfSize:fontSize];
16 | label.attributedText = self;
17 | return [label sizeThatFits:CGSizeMake(MAXFLOAT, limitH)].width;
18 | }
19 | - (CGFloat)zx_getAttrRectHeightWithLimitW:(CGFloat)limitW fontSize:(CGFloat)fontSize{
20 | UILabel *label = [[UILabel alloc]init];
21 | label.font = [UIFont systemFontOfSize:fontSize];
22 | label.attributedText = self;
23 | return [label sizeThatFits:CGSizeMake(limitW,MAXFLOAT )].height;
24 | }
25 | @end
26 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoSystemBarViewController/DemoPublicSystemBarViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoPublicSystemBarViewController.m
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/8/4.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import "DemoPublicSystemBarViewController.h"
10 | #import "DemoXibViewController.h"
11 |
12 | @interface DemoPublicSystemBarViewController ()
13 |
14 | @end
15 |
16 | @implementation DemoPublicSystemBarViewController
17 |
18 | - (void)viewDidLoad {
19 | [super viewDidLoad];
20 | self.title = @"系统导航栏";
21 | self.view.backgroundColor = [UIColor whiteColor];
22 |
23 | UILabel *label = [[UILabel alloc]init];
24 | label.frame = CGRectMake(0, 10, [UIScreen mainScreen].bounds.size.width, 20);
25 | label.textAlignment = NSTextAlignmentCenter;
26 | label.text = @"这是一个系统导航栏的控制器";
27 | [self.view addSubview:label];
28 |
29 | //注意,因导航栏默认被隐藏,请手动设置显示导航栏
30 | self.navigationController.navigationBarHidden = NO;
31 | //如果希望view从导航栏下方开始,请设置导航栏为不透明
32 | self.navigationController.navigationBar.translucent = NO;
33 | }
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/UIImage+ZXNavColorRender.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+ZXNavColorRender.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/10.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "UIImage+ZXNavColorRender.h"
11 |
12 | @implementation UIImage (ZXNavColorRender)
13 | - (UIImage *)zx_renderingColor:(UIColor *)color{
14 | UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
15 | CGContextRef context = UIGraphicsGetCurrentContext();
16 | CGContextTranslateCTM(context, 0, self.size.height);
17 | CGContextScaleCTM(context, 1.0, -1.0);
18 | CGContextSetBlendMode(context, kCGBlendModeNormal);
19 | CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
20 | CGContextClipToMask(context, rect, self.CGImage);
21 | [color setFill];
22 | CGContextFillRect(context, rect);
23 | UIImage *renderedImage = UIGraphicsGetImageFromCurrentImageContext();
24 | UIGraphicsEndImageContext();
25 | return renderedImage;
26 | }
27 | @end
28 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/NSString+ZXNavCalcSizeExtension.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+ZXNavCalcSizeExtension.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/7.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "NSString+ZXNavCalcSizeExtension.h"
11 |
12 | @implementation NSString (ZXNavCalcSizeExtension)
13 | - (CGFloat)zx_getRectWidthWithLimitH:(CGFloat)limitH fontSize:(CGFloat)fontSize{
14 | CGRect rect = [self boundingRectWithSize:CGSizeMake(MAXFLOAT, limitH)
15 | options:NSStringDrawingUsesLineFragmentOrigin
16 | attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]}
17 | context:nil];
18 | return rect.size.width;
19 | }
20 | - (CGFloat)zx_getRectHeightWithLimitW:(CGFloat)limitW fontSize:(CGFloat)fontSize{
21 | CGRect rect = [self boundingRectWithSize:CGSizeMake(limitW,MAXFLOAT )
22 | options:NSStringDrawingUsesLineFragmentOrigin
23 | attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]}
24 | context:nil];
25 | return rect.size.height;
26 | }
27 | @end
28 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/NSString+ZXNavCalcSizeExtension.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+ZXNavCalcSizeExtension.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/7.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "NSString+ZXNavCalcSizeExtension.h"
11 |
12 | @implementation NSString (ZXNavCalcSizeExtension)
13 | - (CGFloat)zx_getRectWidthWithLimitH:(CGFloat)limitH fontSize:(CGFloat)fontSize{
14 | CGRect rect = [self boundingRectWithSize:CGSizeMake(MAXFLOAT, limitH)
15 | options:NSStringDrawingUsesLineFragmentOrigin
16 | attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]}
17 | context:nil];
18 | return rect.size.width;
19 | }
20 | - (CGFloat)zx_getRectHeightWithLimitW:(CGFloat)limitW fontSize:(CGFloat)fontSize{
21 | CGRect rect = [self boundingRectWithSize:CGSizeMake(limitW,MAXFLOAT )
22 | options:NSStringDrawingUsesLineFragmentOrigin
23 | attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]}
24 | context:nil];
25 | return rect.size.height;
26 | }
27 | @end
28 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemoUITests/ZXNavigationBarDemoUITests.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavigationBarDemoUITests.m
3 | // ZXNavigationBarDemoUITests
4 | //
5 | // Created by 李兆祥 on 2020/3/7.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ZXNavigationBarDemoUITests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation ZXNavigationBarDemoUITests
16 |
17 | - (void)setUp {
18 | // Put setup code here. This method is called before the invocation of each test method in the class.
19 |
20 | // In UI tests it is usually best to stop immediately when a failure occurs.
21 | self.continueAfterFailure = NO;
22 |
23 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
24 | [[[XCUIApplication alloc] init] launch];
25 |
26 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
27 | }
28 |
29 | - (void)tearDown {
30 | // Put teardown code here. This method is called after the invocation of each test method in the class.
31 | }
32 |
33 | - (void)testExample {
34 | // Use recording to get started writing UI tests.
35 | // Use XCTAssert and related functions to verify your tests produce the correct results.
36 | }
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoCustomNavViewController/DemoCustomNavViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoCustomNavViewController.m
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/12.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import "DemoCustomNavViewController.h"
10 | #import "DemoCustomNav.h"
11 | @interface DemoCustomNavViewController()
12 | @property (weak, nonatomic) UILabel *noticeLabel;
13 | @end
14 | @implementation DemoCustomNavViewController
15 | - (void)viewDidLoad {
16 | [super viewDidLoad];
17 | [self setUpNav];
18 | [self setUpView];
19 | }
20 |
21 | - (void)setUpNav{
22 | DemoCustomNav *customNav = [[[NSBundle mainBundle]loadNibNamed:NSStringFromClass([DemoCustomNav class]) owner:nil options:nil]lastObject];
23 | [self zx_addCustomNavBar:customNav];
24 | }
25 |
26 | - (void)setUpView{
27 | self.view.backgroundColor = [UIColor whiteColor];
28 | UILabel *noticeLabel = [[UILabel alloc]init];
29 | noticeLabel.textAlignment = NSTextAlignmentCenter;
30 | noticeLabel.text = @"使用侧滑手势可以返回主页";
31 | noticeLabel.textColor = [UIColor lightGrayColor];
32 | [self.view addSubview:noticeLabel];
33 | self.noticeLabel = noticeLabel;
34 | }
35 |
36 | - (void)viewDidLayoutSubviews{
37 | [super viewDidLayoutSubviews];
38 | self.noticeLabel.frame = CGRectMake(0, ZXNavBarHeight + 10, self.view.frame.size.width, 30);
39 | }
40 | @end
41 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarNavigationController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavigationBarNavigationController.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/5/29.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface ZXNavigationBarNavigationController : UINavigationController
15 |
16 | /**
17 | 是否禁用push控制器自动隐藏tabbar
18 | */
19 | @property (assign, nonatomic)BOOL zx_disableAutoHidesBottomBarWhenPushed;
20 |
21 | /**
22 | pop返回手势对象
23 | */
24 | @property (strong, nonatomic, readonly) UIPanGestureRecognizer *zx_popGestureRecognizer;
25 |
26 | /**
27 | 是否禁用全屏pop手势,若禁用,则pop触发范围为屏幕宽度的十分之一
28 | */
29 | @property (assign, nonatomic)BOOL zx_disableFullScreenGesture;
30 |
31 |
32 | /**
33 | pop手势的触发范围比例,0-1,默认为1,即代表全屏触发
34 | */
35 | @property (assign, nonatomic) CGFloat zx_popGestureCoverRatio;
36 |
37 | /**
38 | 监听自定义pop手势进度。currentViewController代表当前正在pop的控制器,popOffsetProgress范围为0-1,0代表即将开始pop,1代表完成pop
39 | */
40 | @property(copy, nonatomic)void(^zx_handleCustomPopGesture)(UIViewController *currentViewController,CGFloat popOffsetProgress);
41 |
42 | /**
43 | pop手势是否支持多层级的手势同时触发,默认为否
44 | */
45 | @property(copy, nonatomic)BOOL(^zx_popGestureShouldRecognizeSimultaneously)(UIGestureRecognizer *otherGestureRecognizer);
46 |
47 | /**
48 | 拦截导航控制器侧滑返回手势,若返回NO,则禁止pop;
49 | topViewController:当前控制器
50 | */
51 | @property(copy, nonatomic)BOOL(^zx_navHandlePopGestureBlock)(UIViewController *topViewController);
52 | @end
53 |
54 | NS_ASSUME_NONNULL_END
55 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarNavigationController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavigationBarNavigationController.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/5/29.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface ZXNavigationBarNavigationController : UINavigationController
15 |
16 | /**
17 | 是否禁用push控制器自动隐藏tabbar
18 | */
19 | @property (assign, nonatomic)BOOL zx_disableAutoHidesBottomBarWhenPushed;
20 |
21 | /**
22 | pop返回手势对象
23 | */
24 | @property (strong, nonatomic, readonly) UIPanGestureRecognizer *zx_popGestureRecognizer;
25 |
26 | /**
27 | 是否禁用全屏pop手势,若禁用,则pop触发范围为屏幕宽度的十分之一
28 | */
29 | @property (assign, nonatomic)BOOL zx_disableFullScreenGesture;
30 |
31 |
32 | /**
33 | pop手势的触发范围比例,0-1,默认为1,即代表全屏触发
34 | */
35 | @property (assign, nonatomic) CGFloat zx_popGestureCoverRatio;
36 |
37 | /**
38 | 监听自定义pop手势进度。currentViewController代表当前正在pop的控制器,popOffsetProgress范围为0-1,0代表即将开始pop,1代表完成pop
39 | */
40 | @property(copy, nonatomic)void(^zx_handleCustomPopGesture)(UIViewController *currentViewController,CGFloat popOffsetProgress);
41 |
42 | /**
43 | pop手势是否支持多层级的手势同时触发,默认为否
44 | */
45 | @property(copy, nonatomic)BOOL(^zx_popGestureShouldRecognizeSimultaneously)(UIGestureRecognizer *otherGestureRecognizer);
46 |
47 | /**
48 | 拦截导航控制器侧滑返回手势,若返回NO,则禁止pop;
49 | topViewController:当前控制器
50 | */
51 | @property(copy, nonatomic)BOOL(^zx_navHandlePopGestureBlock)(UIViewController *topViewController);
52 | @end
53 |
54 | NS_ASSUME_NONNULL_END
55 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIUserInterfaceStyle
6 | Light
7 | NSAppTransportSecurity
8 |
9 | NSAllowsArbitraryLoads
10 |
11 |
12 | CFBundleDevelopmentRegion
13 | $(DEVELOPMENT_LANGUAGE)
14 | CFBundleExecutable
15 | $(EXECUTABLE_NAME)
16 | CFBundleIdentifier
17 | $(PRODUCT_BUNDLE_IDENTIFIER)
18 | CFBundleInfoDictionaryVersion
19 | 6.0
20 | CFBundleName
21 | $(PRODUCT_NAME)
22 | CFBundlePackageType
23 | APPL
24 | CFBundleShortVersionString
25 | 1.0
26 | CFBundleVersion
27 | 1
28 | LSRequiresIPhoneOS
29 |
30 | UILaunchStoryboardName
31 | LaunchScreen
32 | UIRequiredDeviceCapabilities
33 |
34 | armv7
35 |
36 | UISupportedInterfaceOrientations
37 |
38 | UIInterfaceOrientationPortrait
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UISupportedInterfaceOrientations~ipad
43 |
44 | UIInterfaceOrientationPortrait
45 | UIInterfaceOrientationPortraitUpsideDown
46 | UIInterfaceOrientationLandscapeLeft
47 | UIInterfaceOrientationLandscapeRight
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/UINavigationController+ZXNavBarAllHiddenExtension.m:
--------------------------------------------------------------------------------
1 | //
2 | // UINavigationController+ZXNavBarAllHiddenExtension.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/20.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "UINavigationController+ZXNavBarAllHiddenExtension.h"
11 | #import
12 | static BOOL isHideAllNavBar = NO;
13 | @implementation UINavigationController (ZXNavBarAllHiddenExtension)
14 | + (void)zx_hideAllNavBar{
15 | isHideAllNavBar = YES;
16 | zx_nav_swizzleMethod([self class], @selector(pushViewController:animated:), @selector(swizzled_pushViewController:animated:));
17 | }
18 |
19 | + (void)zx_removeAllNavBar{
20 | isHideAllNavBar = NO;
21 | }
22 |
23 | - (void)swizzled_pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
24 | [self swizzled_pushViewController:viewController animated:animated];
25 | Class zxNavVcCls1 = NSClassFromString(@"ZXNavigationBarController");
26 | Class zxNavVcCls2 = NSClassFromString(@"ZXNavigationBarTableViewController");
27 | if(isHideAllNavBar && ([viewController isKindOfClass:zxNavVcCls1] || [viewController isKindOfClass:zxNavVcCls2])){
28 | self.navigationBarHidden = YES;
29 | }
30 | }
31 |
32 | void zx_nav_swizzleMethod(Class class, SEL originalSelector, SEL swizzledSelector){
33 | Method originalMethod = class_getInstanceMethod(class, originalSelector);
34 | Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
35 | BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
36 |
37 | if (didAddMethod) {
38 | class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
39 | }
40 | else {
41 | method_exchangeImplementations(originalMethod, swizzledMethod);
42 | }
43 |
44 | }
45 | @end
46 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/UINavigationController+ZXNavBarAllHiddenExtension.m:
--------------------------------------------------------------------------------
1 | //
2 | // UINavigationController+ZXNavBarAllHiddenExtension.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/20.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "UINavigationController+ZXNavBarAllHiddenExtension.h"
11 | #import
12 | static BOOL isHideAllNavBar = NO;
13 | @implementation UINavigationController (ZXNavBarAllHiddenExtension)
14 | + (void)zx_hideAllNavBar{
15 | isHideAllNavBar = YES;
16 | zx_nav_swizzleMethod([self class], @selector(pushViewController:animated:), @selector(swizzled_pushViewController:animated:));
17 | }
18 |
19 | + (void)zx_removeAllNavBar{
20 | isHideAllNavBar = NO;
21 | }
22 |
23 | - (void)swizzled_pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
24 | [self swizzled_pushViewController:viewController animated:animated];
25 | Class zxNavVcCls1 = NSClassFromString(@"ZXNavigationBarController");
26 | Class zxNavVcCls2 = NSClassFromString(@"ZXNavigationBarTableViewController");
27 | if(isHideAllNavBar && ([viewController isKindOfClass:zxNavVcCls1] || [viewController isKindOfClass:zxNavVcCls2])){
28 | self.navigationBarHidden = YES;
29 | }
30 | }
31 |
32 | void zx_nav_swizzleMethod(Class class, SEL originalSelector, SEL swizzledSelector){
33 | Method originalMethod = class_getInstanceMethod(class, originalSelector);
34 | Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
35 | BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
36 |
37 | if (didAddMethod) {
38 | class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
39 | }
40 | else {
41 | method_exchangeImplementations(originalMethod, swizzledMethod);
42 | }
43 |
44 | }
45 | @end
46 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/ZXNavigationBarController+ZXNavSystemBarPopHandle.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavigationBarController+ZXNavSystemBarPopHandle.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/5/29.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | //Thanks to @onegray https://github.com/onegray/UIViewController-BackButtonHandler Respect!
11 |
12 | #import "ZXNavigationBarController+ZXNavSystemBarPopHandle.h"
13 | #import
14 |
15 | @implementation UIViewController (ZXNavSystemBarPopHandle)
16 |
17 | @end
18 |
19 | @implementation UINavigationController (ZXNavSystemBarPopHandle)
20 |
21 | + (void)load {
22 | Method originalMethod = class_getInstanceMethod([self class], @selector(navigationBar:shouldPopItem:));
23 | Method overloadingMethod = class_getInstanceMethod([self class], @selector(overloaded_navigationBar:shouldPopItem:));
24 | method_setImplementation(originalMethod, method_getImplementation(overloadingMethod));
25 | }
26 |
27 | - (BOOL)overloaded_navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {
28 | if([self.viewControllers count] < [navigationBar.items count]) {
29 | return YES;
30 | }
31 | BOOL shouldPop = YES;
32 | UIViewController* vc = [self topViewController];
33 | if([vc respondsToSelector:@selector(zx_navSystemBarPopHandle)]) {
34 | shouldPop = [vc zx_navSystemBarPopHandle];
35 | }
36 | if(shouldPop) {
37 | dispatch_async(dispatch_get_main_queue(), ^{
38 | [self popViewControllerAnimated:YES];
39 | });
40 | } else {
41 | // Workaround for iOS7.1. Thanks to @boliva - http://stackoverflow.com/posts/comments/34452906
42 | for(UIView *subview in [navigationBar subviews]) {
43 | if(0. < subview.alpha && subview.alpha < 1.) {
44 | [UIView animateWithDuration:.25 animations:^{
45 | subview.alpha = 1.;
46 | }];
47 | }
48 | }
49 | }
50 | return NO;
51 | }
52 |
53 | @end
54 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/ZXNavigationBarController+ZXNavSystemBarPopHandle.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavigationBarController+ZXNavSystemBarPopHandle.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/5/29.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | //Thanks to @onegray https://github.com/onegray/UIViewController-BackButtonHandler Respect!
11 |
12 | #import "ZXNavigationBarController+ZXNavSystemBarPopHandle.h"
13 | #import
14 |
15 | @implementation UIViewController (ZXNavSystemBarPopHandle)
16 |
17 | @end
18 |
19 | @implementation UINavigationController (ZXNavSystemBarPopHandle)
20 |
21 | + (void)load {
22 | Method originalMethod = class_getInstanceMethod([self class], @selector(navigationBar:shouldPopItem:));
23 | Method overloadingMethod = class_getInstanceMethod([self class], @selector(overloaded_navigationBar:shouldPopItem:));
24 | method_setImplementation(originalMethod, method_getImplementation(overloadingMethod));
25 | }
26 |
27 | - (BOOL)overloaded_navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {
28 | if([self.viewControllers count] < [navigationBar.items count]) {
29 | return YES;
30 | }
31 | BOOL shouldPop = YES;
32 | UIViewController* vc = [self topViewController];
33 | if([vc respondsToSelector:@selector(zx_navSystemBarPopHandle)]) {
34 | shouldPop = [vc zx_navSystemBarPopHandle];
35 | }
36 | if(shouldPop) {
37 | dispatch_async(dispatch_get_main_queue(), ^{
38 | [self popViewControllerAnimated:YES];
39 | });
40 | } else {
41 | // Workaround for iOS7.1. Thanks to @boliva - http://stackoverflow.com/posts/comments/34452906
42 | for(UIView *subview in [navigationBar subviews]) {
43 | if(0. < subview.alpha && subview.alpha < 1.) {
44 | [UIView animateWithDuration:.25 animations:^{
45 | subview.alpha = 1.;
46 | }];
47 | }
48 | }
49 | }
50 | return NO;
51 | }
52 |
53 | @end
54 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavHistoryStackView/View/ZXNavHistoryStackCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavHistoryStackCell.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/12/22.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "ZXNavHistoryStackCell.h"
11 | #import "ZXNavHistoryStackModel.h"
12 | #import "ZXNavigationBarDefine.h"
13 | @interface ZXNavHistoryStackCell()
14 | @property (strong, nonatomic) UILabel *contentLabel;
15 | @property (strong, nonatomic) UIView *lineView;
16 | @end
17 | @implementation ZXNavHistoryStackCell
18 |
19 | - (instancetype)initWithFrame:(CGRect)frame{
20 | self = [super initWithFrame:frame];
21 | if(self){
22 | [self setUp];
23 | }
24 | return self;
25 | }
26 |
27 | - (void)setUp{
28 | self.contentLabel = [[UILabel alloc]init];
29 | self.contentLabel.font = [UIFont systemFontOfSize:17];
30 | self.lineView = [[UIView alloc]init];
31 | self.lineView.backgroundColor = [UIColor redColor];
32 | [self.contentView addSubview:self.contentLabel];
33 | [self.contentView addSubview:self.lineView];
34 |
35 | }
36 |
37 | - (void)layoutSubviews{
38 | [super layoutSubviews];
39 | self.contentLabel.frame = CGRectMake(ZXNavHistoryStackCellTitleX, 0, self.frame.size.width - ZXNavHistoryStackCellTitleX * 2, self.frame.size.height);
40 | self.lineView.frame = CGRectMake(0, self.frame.size.height - 0.5, self.frame.size.width, 0.5);
41 | self.lineView.backgroundColor = ZXNavDefalutLineColor;
42 | }
43 |
44 | - (void)setHistoryStackModel:(ZXNavHistoryStackModel *)historyStackModel{
45 | _historyStackModel = historyStackModel;
46 | self.contentLabel.text = historyStackModel.title;
47 | if(self.historyStackViewStyle == ZXNavHistoryStackViewStyleLight){
48 | self.contentView.backgroundColor = ZXNavHistoryStackViewStyleLightBackgroundColor;
49 | self.contentLabel.textColor = [UIColor blackColor];
50 | }else{
51 | self.contentLabel.textColor = [UIColor whiteColor];
52 | self.contentView.backgroundColor = ZXNavHistoryStackViewStyleDarkBackgroundColor;
53 | }
54 | if(historyStackModel.isSelected){
55 | if(self.historyStackViewStyle == ZXNavHistoryStackViewStyleLight){
56 | self.contentView.backgroundColor = ZXNavHistoryStackViewStyleLightSelectedColor;
57 | }else{
58 | self.contentView.backgroundColor = ZXNavHistoryStackViewStyleDarkSelectedColor;
59 | }
60 | }
61 | }
62 | @end
63 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavHistoryStackView/View/ZXNavHistoryStackCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavHistoryStackCell.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/12/22.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "ZXNavHistoryStackCell.h"
11 | #import "ZXNavHistoryStackModel.h"
12 | #import "ZXNavigationBarDefine.h"
13 | @interface ZXNavHistoryStackCell()
14 | @property (strong, nonatomic) UILabel *contentLabel;
15 | @property (strong, nonatomic) UIView *lineView;
16 | @end
17 | @implementation ZXNavHistoryStackCell
18 |
19 | - (instancetype)initWithFrame:(CGRect)frame{
20 | self = [super initWithFrame:frame];
21 | if(self){
22 | [self setUp];
23 | }
24 | return self;
25 | }
26 |
27 | - (void)setUp{
28 | self.contentLabel = [[UILabel alloc]init];
29 | self.contentLabel.font = [UIFont systemFontOfSize:17];
30 | self.lineView = [[UIView alloc]init];
31 | self.lineView.backgroundColor = [UIColor redColor];
32 | [self.contentView addSubview:self.contentLabel];
33 | [self.contentView addSubview:self.lineView];
34 |
35 | }
36 |
37 | - (void)layoutSubviews{
38 | [super layoutSubviews];
39 | self.contentLabel.frame = CGRectMake(ZXNavHistoryStackCellTitleX, 0, self.frame.size.width - ZXNavHistoryStackCellTitleX * 2, self.frame.size.height);
40 | self.lineView.frame = CGRectMake(0, self.frame.size.height - 0.5, self.frame.size.width, 0.5);
41 | self.lineView.backgroundColor = ZXNavDefalutLineColor;
42 | }
43 |
44 | - (void)setHistoryStackModel:(ZXNavHistoryStackModel *)historyStackModel{
45 | _historyStackModel = historyStackModel;
46 | self.contentLabel.text = historyStackModel.title;
47 | if(self.historyStackViewStyle == ZXNavHistoryStackViewStyleLight){
48 | self.contentView.backgroundColor = ZXNavHistoryStackViewStyleLightBackgroundColor;
49 | self.contentLabel.textColor = [UIColor blackColor];
50 | }else{
51 | self.contentLabel.textColor = [UIColor whiteColor];
52 | self.contentView.backgroundColor = ZXNavHistoryStackViewStyleDarkBackgroundColor;
53 | }
54 | if(historyStackModel.isSelected){
55 | if(self.historyStackViewStyle == ZXNavHistoryStackViewStyleLight){
56 | self.contentView.backgroundColor = ZXNavHistoryStackViewStyleLightSelectedColor;
57 | }else{
58 | self.contentView.backgroundColor = ZXNavHistoryStackViewStyleDarkSelectedColor;
59 | }
60 | }
61 | }
62 | @end
63 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/7.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import "DemoListViewController.h"
11 | #import "ZXNavigationBarNavigationController.h"
12 | @interface AppDelegate ()
13 |
14 | @end
15 |
16 | @implementation AppDelegate
17 |
18 |
19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
20 | UIWindow *window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
21 | DemoListViewController *vc = [[DemoListViewController alloc]init];
22 | ZXNavigationBarNavigationController *nav = [[ZXNavigationBarNavigationController alloc]initWithRootViewController:vc];
23 | window.rootViewController = nav;
24 | [window makeKeyAndVisible];
25 | self.window = window;
26 | return YES;
27 | }
28 |
29 |
30 | - (void)applicationWillResignActive:(UIApplication *)application {
31 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
32 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
33 | }
34 |
35 |
36 | - (void)applicationDidEnterBackground:(UIApplication *)application {
37 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
38 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
39 | }
40 |
41 |
42 | - (void)applicationWillEnterForeground:(UIApplication *)application {
43 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
44 | }
45 |
46 |
47 | - (void)applicationDidBecomeActive:(UIApplication *)application {
48 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
49 | }
50 |
51 |
52 | - (void)applicationWillTerminate:(UIApplication *)application {
53 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
54 | }
55 |
56 |
57 | @end
58 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/UIView+ZXNavFrameExtension.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+ZXNavFrameExtension.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/7.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "UIView+ZXNavFrameExtension.h"
11 |
12 | @implementation UIView (ZXNavFrameExtension)
13 | - (CGFloat)zx_x{
14 | return self.frame.origin.x;
15 | }
16 |
17 | - (void)setZx_x:(CGFloat)zx_x{
18 | self.frame = CGRectMake(zx_x, self.zx_y, self.zx_width, self.zx_height);
19 | }
20 |
21 | - (CGFloat)zx_y{
22 | return self.frame.origin.y;
23 | }
24 |
25 | - (void)setZx_y:(CGFloat)zx_y{
26 | self.frame = CGRectMake(self.zx_x, zx_y, self.zx_width, self.zx_height);
27 | }
28 |
29 | - (CGFloat)zx_width{
30 | return self.frame.size.width;
31 | }
32 |
33 | - (void)setZx_width:(CGFloat)zx_width{
34 | self.frame = CGRectMake(self.zx_x, self.zx_y, zx_width, self.zx_height);
35 | }
36 |
37 | - (CGFloat)zx_height{
38 | return self.frame.size.height;
39 | }
40 |
41 | - (void)setZx_height:(CGFloat)zx_height{
42 | self.frame = CGRectMake(self.zx_x, self.zx_y, self.zx_width, zx_height);
43 | }
44 |
45 | - (CGFloat)zx_right{
46 | return self.frame.origin.x + self.frame.size.width;
47 | }
48 |
49 | - (void)setZx_right:(CGFloat)zx_right{
50 | CGRect frame = self.frame;
51 | frame.origin.x = zx_right - frame.size.width;
52 | self.frame = frame;
53 | }
54 |
55 | - (CGFloat)zx_bottom{
56 | return self.frame.origin.y + self.frame.size.height;
57 | }
58 |
59 | - (void)setZx_bottom:(CGFloat)zx_bottom{
60 | CGRect frame = self.frame;
61 | frame.origin.y = zx_bottom - frame.size.height;
62 | self.frame = frame;
63 | }
64 |
65 | - (CGFloat)zx_centerX{
66 | return self.center.x;
67 | }
68 |
69 | - (void)setZx_centerX:(CGFloat)zx_centerX{
70 | self.center = CGPointMake(zx_centerX, self.center.y);
71 | }
72 |
73 | - (CGFloat)zx_centerY{
74 | return self.center.y;
75 | }
76 |
77 | - (void)setZx_centerY:(CGFloat)zx_centerY{
78 | self.center = CGPointMake(self.center.x, zx_centerY);
79 | }
80 |
81 | - (CGPoint)zx_origin{
82 | return self.frame.origin;
83 | }
84 |
85 | - (void)setZx_origin:(CGPoint)zx_origin{
86 | CGRect frame = self.frame;
87 | frame.origin = zx_origin;
88 | self.frame = frame;
89 | }
90 |
91 | - (CGSize)zx_size{
92 | return self.frame.size;
93 | }
94 |
95 | - (void)setZx_size:(CGSize)zx_size{
96 | CGRect frame = self.frame;
97 | frame.size = zx_size;
98 | self.frame = frame;
99 | }
100 | @end
101 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarHelper/ZXNavigationBarCategory/UIView+ZXNavFrameExtension.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+ZXNavFrameExtension.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/7.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "UIView+ZXNavFrameExtension.h"
11 |
12 | @implementation UIView (ZXNavFrameExtension)
13 | - (CGFloat)zx_x{
14 | return self.frame.origin.x;
15 | }
16 |
17 | - (void)setZx_x:(CGFloat)zx_x{
18 | self.frame = CGRectMake(zx_x, self.zx_y, self.zx_width, self.zx_height);
19 | }
20 |
21 | - (CGFloat)zx_y{
22 | return self.frame.origin.y;
23 | }
24 |
25 | - (void)setZx_y:(CGFloat)zx_y{
26 | self.frame = CGRectMake(self.zx_x, zx_y, self.zx_width, self.zx_height);
27 | }
28 |
29 | - (CGFloat)zx_width{
30 | return self.frame.size.width;
31 | }
32 |
33 | - (void)setZx_width:(CGFloat)zx_width{
34 | self.frame = CGRectMake(self.zx_x, self.zx_y, zx_width, self.zx_height);
35 | }
36 |
37 | - (CGFloat)zx_height{
38 | return self.frame.size.height;
39 | }
40 |
41 | - (void)setZx_height:(CGFloat)zx_height{
42 | self.frame = CGRectMake(self.zx_x, self.zx_y, self.zx_width, zx_height);
43 | }
44 |
45 | - (CGFloat)zx_right{
46 | return self.frame.origin.x + self.frame.size.width;
47 | }
48 |
49 | - (void)setZx_right:(CGFloat)zx_right{
50 | CGRect frame = self.frame;
51 | frame.origin.x = zx_right - frame.size.width;
52 | self.frame = frame;
53 | }
54 |
55 | - (CGFloat)zx_bottom{
56 | return self.frame.origin.y + self.frame.size.height;
57 | }
58 |
59 | - (void)setZx_bottom:(CGFloat)zx_bottom{
60 | CGRect frame = self.frame;
61 | frame.origin.y = zx_bottom - frame.size.height;
62 | self.frame = frame;
63 | }
64 |
65 | - (CGFloat)zx_centerX{
66 | return self.center.x;
67 | }
68 |
69 | - (void)setZx_centerX:(CGFloat)zx_centerX{
70 | self.center = CGPointMake(zx_centerX, self.center.y);
71 | }
72 |
73 | - (CGFloat)zx_centerY{
74 | return self.center.y;
75 | }
76 |
77 | - (void)setZx_centerY:(CGFloat)zx_centerY{
78 | self.center = CGPointMake(self.center.x, zx_centerY);
79 | }
80 |
81 | - (CGPoint)zx_origin{
82 | return self.frame.origin;
83 | }
84 |
85 | - (void)setZx_origin:(CGPoint)zx_origin{
86 | CGRect frame = self.frame;
87 | frame.origin = zx_origin;
88 | self.frame = frame;
89 | }
90 |
91 | - (CGSize)zx_size{
92 | return self.frame.size;
93 | }
94 |
95 | - (void)setZx_size:(CGSize)zx_size{
96 | CGRect frame = self.frame;
97 | frame.size = zx_size;
98 | self.frame = frame;
99 | }
100 | @end
101 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavItemBtn.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavItemBtn.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/7.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface ZXNavItemBtn : UIButton
15 | ///是否禁止设置title和attributedTitle
16 | @property (assign, nonatomic, readonly)BOOL zx_disableSetTitle;
17 | ///NavItemBtn的frame更新回调
18 | @property (copy, nonatomic) void (^zx_barItemBtnFrameUpdateBlock)(ZXNavItemBtn *barItemBtn);
19 | ///设置NavItemBtn的image颜色
20 | @property (strong, nonatomic, nullable)UIColor *zx_imageColor;
21 | ///设置NavItemBtn的tintColor
22 | @property (strong, nonatomic, nullable)UIColor *zx_tintColor;
23 | ///设置NavItemBtn的tintColor仅用于UIControlStateNormal状态(请在zx_imageColor和zx_tintColor之前设置),默认为NO
24 | @property (assign, nonatomic)UIColor *zx_useTintColorOnlyInStateNormal;
25 | ///设置NavItemBtn的字体大小
26 | @property (assign, nonatomic)CGFloat zx_fontSize;
27 | ///禁止自动调整按钮图片和文字的布局,若要使contentEdgeInsets、titleEdgeInsets、imageEdgeInsets等,则需要将此属性设置为NO
28 | @property (assign, nonatomic)BOOL zx_disableAutoLayoutImageAndTitle;
29 | ///设置NavItemBtn的固定宽度,若设置,则自动计算宽度无效,若要恢复初始值,可设置为-1
30 | @property (assign, nonatomic)CGFloat zx_fixWidth;
31 | ///设置NavItemBtn的固定高度,若设置,则ZXNavDefalutItemSize无效,若要恢复初始值,可设置为-1
32 | @property (assign, nonatomic)CGFloat zx_fixHeight;
33 | ///设置NavItemBtn距离左边元素的固定距离,若要恢复初始值,可设置为-1
34 | @property (assign, nonatomic)CGFloat zx_fixMarginLeft;
35 | ///设置NavItemBtn距离右边元素的固定距离,若要恢复初始值,可设置为-1
36 | @property (assign, nonatomic)CGFloat zx_fixMarginRight;
37 | ///设置NavItemBtn image的固定大小,若要恢复初始值,可设置为CGSizeZero
38 | @property (assign, nonatomic)CGSize zx_fixImageSize;
39 | ///设置NavItemBtn文字自动计算宽度后的附加宽度
40 | @property (assign, nonatomic)CGFloat zx_textAttachWidth;
41 | ///设置NavItemBtn文字的附加高度
42 | @property (assign, nonatomic)CGFloat zx_textAttachHeight;
43 | ///设置NavItemBtn的cornerRadius为高度的一半(圆形圆角)
44 | @property (assign, nonatomic)BOOL zx_setCornerRadiusRounded;
45 | ///设置NavItemBtn内部图片x轴的偏移量,负数代表左移,无title且设置了zx_fixImageSize后生效,仅改变内容imageView的位移,不会改变原始NavItemBtn的frame
46 | @property (assign, nonatomic)CGFloat zx_imageOffsetX;
47 | ///设置NavItemBtn的自定义view
48 | @property (strong, nonatomic, nullable)UIView *zx_customView;
49 | ///NavItemBtn frame发生改变时的回调,可在这个block中return修改后的frame
50 | @property(copy, nonatomic)CGRect(^zx_handleFrameBlock)(CGRect oldFrame);
51 | ///开始点击的回调
52 | @property (copy, nonatomic) void (^zx_touchesBeganBlock)(void);
53 | ///结束点击的回调
54 | @property (copy, nonatomic) void (^zx_touchesEndBlock)(void);
55 | ///手动更新布局,一般内部会自动调用,用于高度定制时无法自动更新布局时调用
56 | - (void)zx_updateLayout;
57 | ///刷新NavItemBtn的image和title布局,一般内部会自动调用
58 | - (void)zx_layoutImageAndTitle;
59 | @end
60 |
61 | NS_ASSUME_NONNULL_END
62 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavItemBtn.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavItemBtn.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/7.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 |
12 | NS_ASSUME_NONNULL_BEGIN
13 |
14 | @interface ZXNavItemBtn : UIButton
15 | ///是否禁止设置title和attributedTitle
16 | @property (assign, nonatomic, readonly)BOOL zx_disableSetTitle;
17 | ///NavItemBtn的frame更新回调
18 | @property (copy, nonatomic) void (^zx_barItemBtnFrameUpdateBlock)(ZXNavItemBtn *barItemBtn);
19 | ///设置NavItemBtn的image颜色
20 | @property (strong, nonatomic, nullable)UIColor *zx_imageColor;
21 | ///设置NavItemBtn的tintColor
22 | @property (strong, nonatomic, nullable)UIColor *zx_tintColor;
23 | ///设置NavItemBtn的tintColor仅用于UIControlStateNormal状态(请在zx_imageColor和zx_tintColor之前设置),默认为NO
24 | @property (assign, nonatomic)UIColor *zx_useTintColorOnlyInStateNormal;
25 | ///设置NavItemBtn的字体大小
26 | @property (assign, nonatomic)CGFloat zx_fontSize;
27 | ///禁止自动调整按钮图片和文字的布局,若要使contentEdgeInsets、titleEdgeInsets、imageEdgeInsets等,则需要将此属性设置为NO
28 | @property (assign, nonatomic)BOOL zx_disableAutoLayoutImageAndTitle;
29 | ///设置NavItemBtn的固定宽度,若设置,则自动计算宽度无效,若要恢复初始值,可设置为-1
30 | @property (assign, nonatomic)CGFloat zx_fixWidth;
31 | ///设置NavItemBtn的固定高度,若设置,则ZXNavDefalutItemSize无效,若要恢复初始值,可设置为-1
32 | @property (assign, nonatomic)CGFloat zx_fixHeight;
33 | ///设置NavItemBtn距离左边元素的固定距离,若要恢复初始值,可设置为-1
34 | @property (assign, nonatomic)CGFloat zx_fixMarginLeft;
35 | ///设置NavItemBtn距离右边元素的固定距离,若要恢复初始值,可设置为-1
36 | @property (assign, nonatomic)CGFloat zx_fixMarginRight;
37 | ///设置NavItemBtn image的固定大小,若要恢复初始值,可设置为CGSizeZero
38 | @property (assign, nonatomic)CGSize zx_fixImageSize;
39 | ///设置NavItemBtn文字自动计算宽度后的附加宽度
40 | @property (assign, nonatomic)CGFloat zx_textAttachWidth;
41 | ///设置NavItemBtn文字的附加高度
42 | @property (assign, nonatomic)CGFloat zx_textAttachHeight;
43 | ///设置NavItemBtn的cornerRadius为高度的一半(圆形圆角)
44 | @property (assign, nonatomic)BOOL zx_setCornerRadiusRounded;
45 | ///设置NavItemBtn内部图片x轴的偏移量,负数代表左移,无title且设置了zx_fixImageSize后生效,仅改变内容imageView的位移,不会改变原始NavItemBtn的frame
46 | @property (assign, nonatomic)CGFloat zx_imageOffsetX;
47 | ///设置NavItemBtn的自定义view
48 | @property (strong, nonatomic, nullable)UIView *zx_customView;
49 | ///NavItemBtn frame发生改变时的回调,可在这个block中return修改后的frame
50 | @property(copy, nonatomic)CGRect(^zx_handleFrameBlock)(CGRect oldFrame);
51 | ///开始点击的回调
52 | @property (copy, nonatomic) void (^zx_touchesBeganBlock)(void);
53 | ///结束点击的回调
54 | @property (copy, nonatomic) void (^zx_touchesEndBlock)(void);
55 | ///手动更新布局,一般内部会自动调用,用于高度定制时无法自动更新布局时调用
56 | - (void)zx_updateLayout;
57 | ///刷新NavItemBtn的image和title布局,一般内部会自动调用
58 | - (void)zx_layoutImageAndTitle;
59 | @end
60 |
61 | NS_ASSUME_NONNULL_END
62 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoFoldXibViewController/DemoFoldXibViewController.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 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoFoldXibViewController/DemoFoldXibViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoFoldXibViewController.m
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/13.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import "DemoFoldXibViewController.h"
10 |
11 | @interface DemoFoldXibViewController ()
12 | @property (weak, nonatomic) IBOutlet UITableView *tableView;
13 | @property (strong, nonatomic) NSArray *datas;
14 | @property (assign, nonatomic) CGFloat lastOffsetY;
15 |
16 | @end
17 |
18 | @implementation DemoFoldXibViewController
19 |
20 | - (void)viewDidLoad {
21 | [super viewDidLoad];
22 | [self setUpNav];
23 | [self setUpViewAndData];
24 | }
25 |
26 | - (void)setUpNav{
27 | self.title = @"可伸缩式导航栏";
28 | self.zx_navStatusBarStyle = ZXNavStatusBarStyleLight;
29 | [self.zx_navLeftBtn setTitle:@"首页" forState:UIControlStateNormal];
30 | self.zx_navBar.backgroundColor = [UIColor colorWithRed:16/255.0 green:94/255.0 blue:253/255.0 alpha:1];
31 | self.zx_navTintColor = [UIColor whiteColor];
32 | [self zx_setRightBtnWithImgName:@"recycle_icon" clickedBlock:nil];
33 | }
34 |
35 | - (void)setUpViewAndData{
36 | self.view.backgroundColor = [UIColor whiteColor];
37 | self.datas = @[@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳"];
38 | self.tableView.delegate = self;
39 | self.tableView.dataSource = self;
40 | }
41 | #pragma mark - UITableViewDataSource & UITableViewDelegate
42 | - (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
43 | return self.datas.count;
44 | }
45 |
46 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
47 | UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
48 | cell.textLabel.text = self.datas[indexPath.row];
49 | return cell;
50 | }
51 |
52 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
53 | return 50;
54 | }
55 |
56 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
57 | [tableView deselectRowAtIndexPath:indexPath animated:NO];
58 | }
59 |
60 | #pragma mark - UIScrollViewDelegate
61 |
62 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView{
63 |
64 | CGFloat offsetY = scrollView.contentOffset.y;
65 | CGFloat distanceFromBottom = scrollView.contentSize.height - offsetY;
66 | CGFloat distance = offsetY - self.lastOffsetY;
67 | self.lastOffsetY = offsetY;
68 | if (distance > 0 && offsetY > 0) {
69 | //向上滚动,导航栏折叠
70 | if(!self.zx_navIsFolded){
71 | //如果没有折叠 就折叠
72 | [self setNavFold:YES];
73 | }
74 |
75 | }
76 | if (distance < 0 && distanceFromBottom > scrollView.zx_height) {
77 | //向下滚动
78 | if(self.zx_navIsFolded){
79 | //如果有折叠 就展开
80 | [self setNavFold:NO];
81 | }
82 |
83 | }
84 | }
85 |
86 | - (void)setNavFold:(BOOL)shouldFold{
87 | [self zx_setNavFolded:shouldFold speed:3 foldingOffsetBlock:nil foldCompletionBlock:nil];
88 | }
89 |
90 | @end
91 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBar.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavigationBar.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/7.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 | #import "ZXNavigationBarDefine.h"
12 | #import "UIImage+ZXNavColorRender.h"
13 | #import "UIView+ZXNavFrameExtension.h"
14 | #import "NSString+ZXNavCalcSizeExtension.h"
15 | #import "NSAttributedString+ZXNavCalcSizeExtension.h"
16 | #import "ZXNavTitleLabel.h"
17 | #import "ZXNavItemBtn.h"
18 | #import "ZXNavBacImageView.h"
19 | #import "ZXNavTitleView.h"
20 | NS_ASSUME_NONNULL_BEGIN
21 |
22 | @interface ZXNavigationBar : UIView
23 | /**
24 | 设置左右Button的大小(宽高相等)
25 | */
26 | @property (assign, nonatomic)CGFloat zx_itemSize;
27 | /**
28 | 设置Item之间的间距
29 | */
30 | @property (assign, nonatomic)CGFloat zx_itemMargin;
31 | /**
32 | 最左侧Button
33 | */
34 | @property (weak, nonatomic)ZXNavItemBtn *zx_leftBtn;
35 | /**
36 | 左侧第二个Button
37 | */
38 | @property (weak, nonatomic)ZXNavItemBtn *zx_subLeftBtn;
39 | /**
40 | 最右侧Button
41 | */
42 | @property (weak, nonatomic)ZXNavItemBtn *zx_rightBtn;
43 | /**
44 | 右侧第二个Button
45 | */
46 | @property (weak, nonatomic)ZXNavItemBtn *zx_subRightBtn;
47 | /**
48 | titleView,显示在正中间的标题View
49 | */
50 | @property (weak, nonatomic, readonly)ZXNavTitleView *zx_titleView;
51 | /**
52 | titleLabel,显示在正中间的标题Label
53 | */
54 | @property (weak, nonatomic)ZXNavTitleLabel *zx_titleLabel;
55 | /**
56 | 导航栏背景ImageView
57 | */
58 | @property (weak, nonatomic)ZXNavBacImageView *zx_bacImageView;
59 | /**
60 | 导航栏背景渐变的CAGradientLayer
61 | */
62 | @property (weak, nonatomic, nullable)CAGradientLayer *zx_gradientLayer;
63 | /**
64 | 导航栏背景图片
65 | */
66 | @property (strong, nonatomic ,nullable)UIImage *zx_bacImage;
67 | /**
68 | 是否开启系统导航栏与自定义导航栏平滑过渡(务必仅当存在系统导航栏与自定义导航栏过渡时启用,非必要请勿启用,否则可能造成自定义导航栏跳动,若当前控制器显示了系统导航栏,请于当前控制器pop的上一个控制器中使用self.zx_navEnableSmoothFromSystemNavBar = YES)
69 | */
70 | @property (assign, nonatomic, readonly)BOOL zx_navEnableSmoothFromSystemNavBar;
71 | /**
72 | 自定义的titleView,是TitleView的SubView
73 | */
74 | @property (weak, nonatomic)UIView *zx_customTitleView;
75 | /**
76 | 自定义的导航栏View,是ZXNavigationBar的SubView
77 | */
78 | @property (weak, nonatomic)UIView *zx_customNavBar;
79 | /**
80 | 分割线
81 | */
82 | @property (weak, nonatomic)UIView *lineView ZXNavigationBarDeprecated("从版本1.3.6起,此属性过期,请使用zx_lineView");
83 | /**
84 | 分割线
85 | */
86 | @property (weak, nonatomic)UIView *zx_lineView;
87 | /**
88 | 分割线的高度,默认为1
89 | */
90 | @property (assign, nonatomic)CGFloat zx_lineViewHeight;
91 | /**
92 | 最左侧Button点击回调
93 | */
94 | @property (copy, nonatomic) void (^zx_leftBtnClickedBlock)(ZXNavItemBtn *btn);
95 | /**
96 | 左侧第二个Button点击回调
97 | */
98 | @property (copy, nonatomic) void (^zx_subLeftBtnClickedBlock)(ZXNavItemBtn *btn);
99 | /**
100 | 最右侧Button点击回调
101 | */
102 | @property (copy, nonatomic) void (^zx_rightBtnClickedBlock)(ZXNavItemBtn *btn);
103 | /**
104 | 右侧第二个Button点击回调
105 | */
106 | @property (copy, nonatomic) void (^zx_subRightBtnClickedBlock)(ZXNavItemBtn *btn);
107 |
108 | /**
109 | 导航栏背景色Components
110 | */
111 | @property (strong, nonatomic, readonly) NSArray* zx_backgroundColorComponents;
112 | /**
113 | 设置大小标题效果
114 |
115 | @param title 大标题
116 | @param subTitle 小标题
117 | */
118 | - (void)zx_setMultiTitle:(NSString *)title subTitle:(NSString *)subTitle;
119 |
120 | /**
121 | 设置大小标题效果
122 |
123 | @param title 大标题
124 | @param subTitle 小标题
125 | @param subTitleFont 小标题字体
126 | @param subTitleColor 小标题颜色
127 | */
128 | - (void)zx_setMultiTitle:(NSString *)title subTitle:(NSString *)subTitle subTitleFont:(UIFont *)subTitleFont subTitleTextColor:(UIColor *)subTitleColor;
129 |
130 | @end
131 |
132 | NS_ASSUME_NONNULL_END
133 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBar.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavigationBar.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/7.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import
11 | #import "ZXNavigationBarDefine.h"
12 | #import "UIImage+ZXNavColorRender.h"
13 | #import "UIView+ZXNavFrameExtension.h"
14 | #import "NSString+ZXNavCalcSizeExtension.h"
15 | #import "NSAttributedString+ZXNavCalcSizeExtension.h"
16 | #import "ZXNavTitleLabel.h"
17 | #import "ZXNavItemBtn.h"
18 | #import "ZXNavBacImageView.h"
19 | #import "ZXNavTitleView.h"
20 | NS_ASSUME_NONNULL_BEGIN
21 |
22 | @interface ZXNavigationBar : UIView
23 | /**
24 | 设置左右Button的大小(宽高相等)
25 | */
26 | @property (assign, nonatomic)CGFloat zx_itemSize;
27 | /**
28 | 设置Item之间的间距
29 | */
30 | @property (assign, nonatomic)CGFloat zx_itemMargin;
31 | /**
32 | 最左侧Button
33 | */
34 | @property (weak, nonatomic)ZXNavItemBtn *zx_leftBtn;
35 | /**
36 | 左侧第二个Button
37 | */
38 | @property (weak, nonatomic)ZXNavItemBtn *zx_subLeftBtn;
39 | /**
40 | 最右侧Button
41 | */
42 | @property (weak, nonatomic)ZXNavItemBtn *zx_rightBtn;
43 | /**
44 | 右侧第二个Button
45 | */
46 | @property (weak, nonatomic)ZXNavItemBtn *zx_subRightBtn;
47 | /**
48 | titleView,显示在正中间的标题View
49 | */
50 | @property (weak, nonatomic, readonly)ZXNavTitleView *zx_titleView;
51 | /**
52 | titleLabel,显示在正中间的标题Label
53 | */
54 | @property (weak, nonatomic)ZXNavTitleLabel *zx_titleLabel;
55 | /**
56 | 导航栏背景ImageView
57 | */
58 | @property (weak, nonatomic)ZXNavBacImageView *zx_bacImageView;
59 | /**
60 | 导航栏背景渐变的CAGradientLayer
61 | */
62 | @property (weak, nonatomic, nullable)CAGradientLayer *zx_gradientLayer;
63 | /**
64 | 导航栏背景图片
65 | */
66 | @property (strong, nonatomic ,nullable)UIImage *zx_bacImage;
67 | /**
68 | 是否开启系统导航栏与自定义导航栏平滑过渡(务必仅当存在系统导航栏与自定义导航栏过渡时启用,非必要请勿启用,否则可能造成自定义导航栏跳动,若当前控制器显示了系统导航栏,请于当前控制器pop的上一个控制器中使用self.zx_navEnableSmoothFromSystemNavBar = YES)
69 | */
70 | @property (assign, nonatomic, readonly)BOOL zx_navEnableSmoothFromSystemNavBar;
71 | /**
72 | 自定义的titleView,是TitleView的SubView
73 | */
74 | @property (weak, nonatomic)UIView *zx_customTitleView;
75 | /**
76 | 自定义的导航栏View,是ZXNavigationBar的SubView
77 | */
78 | @property (weak, nonatomic)UIView *zx_customNavBar;
79 | /**
80 | 分割线
81 | */
82 | @property (weak, nonatomic)UIView *lineView ZXNavigationBarDeprecated("从版本1.3.6起,此属性过期,请使用zx_lineView");
83 | /**
84 | 分割线
85 | */
86 | @property (weak, nonatomic)UIView *zx_lineView;
87 | /**
88 | 分割线的高度,默认为1
89 | */
90 | @property (assign, nonatomic)CGFloat zx_lineViewHeight;
91 | /**
92 | 最左侧Button点击回调
93 | */
94 | @property (copy, nonatomic) void (^zx_leftBtnClickedBlock)(ZXNavItemBtn *btn);
95 | /**
96 | 左侧第二个Button点击回调
97 | */
98 | @property (copy, nonatomic) void (^zx_subLeftBtnClickedBlock)(ZXNavItemBtn *btn);
99 | /**
100 | 最右侧Button点击回调
101 | */
102 | @property (copy, nonatomic) void (^zx_rightBtnClickedBlock)(ZXNavItemBtn *btn);
103 | /**
104 | 右侧第二个Button点击回调
105 | */
106 | @property (copy, nonatomic) void (^zx_subRightBtnClickedBlock)(ZXNavItemBtn *btn);
107 |
108 | /**
109 | 导航栏背景色Components
110 | */
111 | @property (strong, nonatomic, readonly) NSArray* zx_backgroundColorComponents;
112 | /**
113 | 设置大小标题效果
114 |
115 | @param title 大标题
116 | @param subTitle 小标题
117 | */
118 | - (void)zx_setMultiTitle:(NSString *)title subTitle:(NSString *)subTitle;
119 |
120 | /**
121 | 设置大小标题效果
122 |
123 | @param title 大标题
124 | @param subTitle 小标题
125 | @param subTitleFont 小标题字体
126 | @param subTitleColor 小标题颜色
127 | */
128 | - (void)zx_setMultiTitle:(NSString *)title subTitle:(NSString *)subTitle subTitleFont:(UIFont *)subTitleFont subTitleTextColor:(UIColor *)subTitleColor;
129 |
130 | @end
131 |
132 | NS_ASSUME_NONNULL_END
133 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoFoldFrameViewController/DemoFoldFrameViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoTelescopicViewController.m
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/13.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import "DemoFoldFrameViewController.h"
10 |
11 | @interface DemoFoldFrameViewController ()
12 | @property (strong, nonatomic) UITableView *tableView;
13 | @property (strong, nonatomic) NSArray *datas;
14 | @property (assign, nonatomic) CGFloat lastOffsetY;
15 | @end
16 |
17 | @implementation DemoFoldFrameViewController
18 |
19 | - (void)viewDidLoad {
20 | [super viewDidLoad];
21 | [self setUpNav];
22 | [self setUpViewAndData];
23 | }
24 |
25 | - (void)setUpNav{
26 | self.title = @"可伸缩式导航栏(Frame)";
27 | self.zx_navStatusBarStyle = ZXNavStatusBarStyleLight;
28 | [self.zx_navLeftBtn setTitle:@"首页" forState:UIControlStateNormal];
29 | self.zx_navBar.backgroundColor = [UIColor colorWithRed:16/255.0 green:94/255.0 blue:253/255.0 alpha:1];
30 | self.zx_navTintColor = [UIColor whiteColor];
31 | [self zx_setRightBtnWithImgName:@"recycle_icon" clickedBlock:nil];
32 | }
33 |
34 | - (void)setUpViewAndData{
35 | self.view.backgroundColor = [UIColor whiteColor];
36 | self.datas = @[@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳"];
37 | self.tableView = [[UITableView alloc]init];
38 | [self.view addSubview:self.tableView];
39 | self.tableView.delegate = self;
40 | self.tableView.dataSource = self;
41 | self.tableView.frame = CGRectMake(0, ZXNavBarHeight, self.view.frame.size.width, self.view.frame.size.height - ZXNavBarHeight);
42 | }
43 |
44 | #pragma mark - UITableViewDataSource & UITableViewDelegate
45 | - (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
46 | return self.datas.count;
47 | }
48 |
49 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
50 | UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
51 | cell.textLabel.text = self.datas[indexPath.row];
52 | return cell;
53 | }
54 |
55 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
56 | return 50;
57 | }
58 |
59 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
60 | [tableView deselectRowAtIndexPath:indexPath animated:NO];
61 | }
62 |
63 | #pragma mark - UIScrollViewDelegate
64 |
65 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView{
66 |
67 | CGFloat offsetY = scrollView.contentOffset.y;
68 | CGFloat distanceFromBottom = scrollView.contentSize.height - offsetY;
69 | CGFloat distance = offsetY - self.lastOffsetY;
70 | self.lastOffsetY = offsetY;
71 | if (distance > 0 && offsetY > 0) {
72 | //向上滚动,导航栏折叠
73 | if(!self.zx_navIsFolded){
74 | //如果没有折叠 就折叠
75 | [self setNavFold:YES];
76 | }
77 |
78 | }
79 | if (distance < 0 && distanceFromBottom > scrollView.zx_height) {
80 | //向下滚动
81 | if(self.zx_navIsFolded){
82 | //如果有折叠 就展开
83 | [self setNavFold:NO];
84 | }
85 |
86 | }
87 | }
88 |
89 | - (void)setNavFold:(BOOL)shouldFold{
90 | __weak typeof(self) weakSelf = self;
91 | [self zx_setNavFolded:shouldFold speed:3 foldingOffsetBlock:^(CGFloat offset) {
92 | //tableView的y值跟随导航栏变化(导航栏高度减小,tableView的y值减小)
93 | weakSelf.tableView.zx_y += offset;
94 | //tableView的高度值跟随这导航栏变化(导航栏高度减小,tableView高度增加)
95 | weakSelf.tableView.zx_height -= offset;
96 | } foldCompletionBlock:nil];
97 | }
98 | @end
99 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoCompatibleScrollViewViewController/DemoCompatibleScrollViewViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoCompatibleScrollViewViewController.m
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/7/29.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import "DemoCompatibleScrollViewViewController.h"
10 | #define random(r, g, b, a) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:(a)/255.0]
11 | #define randomColor random(arc4random_uniform(200), arc4random_uniform(200), arc4random_uniform(200), 255.0)
12 |
13 | @interface DemoCompatibleScrollViewViewController ()
14 | @property (strong, nonatomic) UIScrollView *scrollView;
15 | @property (strong, nonatomic) UIScrollView *topScrollView;
16 | @end
17 |
18 | @implementation DemoCompatibleScrollViewViewController
19 |
20 | - (void)viewDidLoad {
21 | [super viewDidLoad];
22 | [self setUpNav];
23 | [self setUpView];
24 |
25 | }
26 |
27 | - (void)setUpNav{
28 | [self zx_setMultiTitle:self.title subTitle:@"兼容设置多ScrollView与侧滑返回手势演示"];
29 | //加这一行代码即可解决ScrollView与侧滑返回手势冲突问题(这里演示同时兼容两个scrollView的情况)
30 | [self zx_setPopGestureCompatibleScrollViews:@[self.topScrollView,self.scrollView]];
31 | //当导航控制器为ZXNavigationBarNavigationController或继承于ZXNavigationBarNavigationController时,如果需要更复杂的定制化的情况,可以使用下方的方式,以下代码的作用是在scrollView滚动到第一页的时候,支持pop手势多层级同时触发,为了更好的展示效果,建议关闭scrollView的bounces
32 |
33 | /*
34 | self.scrollView.bounces = NO;
35 | __weak typeof(self) weakSelf = self;
36 | self.zx_popGestureShouldRecognizeSimultaneously = ^BOOL(UIGestureRecognizer * _Nonnull otherGestureRecognizer) {
37 | if(weakSelf.scrollView.contentOffset.x <= 0){
38 | return YES;
39 | }
40 | return NO;
41 | };
42 | */
43 | }
44 |
45 |
46 | - (void)setUpView{
47 | self.view.backgroundColor = [UIColor whiteColor];
48 | [self.view addSubview:self.topScrollView];
49 | [self.view addSubview:self.scrollView];
50 | [self setUpScrollViewData];
51 | }
52 |
53 | - (void)setUpScrollViewData{
54 | [self layoutScrollViewSubviews:self.topScrollView];
55 | [self layoutScrollViewSubviews:self.scrollView];
56 | }
57 |
58 | - (void)layoutScrollViewSubviews:(UIScrollView *)scrollView{
59 | scrollView.pagingEnabled = YES;
60 | UIView *lastView;
61 | [scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
62 | for(int i = 0; i < 10; i++){
63 | UIView *view = [[UIView alloc]init];
64 | view.backgroundColor = randomColor;
65 | view.frame = CGRectMake(i * scrollView.zx_width, 0, scrollView.zx_width, scrollView.zx_height);
66 | UILabel *titleLabel = [[UILabel alloc]init];
67 | titleLabel.frame = view.bounds;
68 | titleLabel.font = [UIFont boldSystemFontOfSize:70];
69 | titleLabel.textAlignment = NSTextAlignmentCenter;
70 | titleLabel.textColor = [UIColor whiteColor];
71 | titleLabel.text = [NSString stringWithFormat:@"%d",i + 1];
72 | [view addSubview:titleLabel];
73 | [scrollView addSubview:view];
74 | lastView = view;
75 | }
76 | if(lastView){
77 | [scrollView setContentSize:CGSizeMake(CGRectGetMaxX(lastView.frame), 0)];
78 | }
79 | [scrollView setContentOffset:CGPointZero];
80 | }
81 |
82 | - (void)viewDidLayoutSubviews{
83 | [super viewDidLayoutSubviews];
84 | self.topScrollView.frame = CGRectMake(0, ZXNavBarHeight, self.view.zx_width, 200);
85 | self.scrollView.frame = CGRectMake(0, ZXNavBarHeight + 200, self.view.zx_width, self.view.zx_height - ZXNavBarHeight - 200);
86 | [self setUpScrollViewData];
87 | }
88 |
89 |
90 | - (UIScrollView *)scrollView{
91 | if(!_scrollView){
92 | _scrollView = [[UIScrollView alloc]init];
93 | [self.view addSubview:_scrollView];
94 | }
95 | return _scrollView;
96 | }
97 |
98 | - (UIScrollView *)topScrollView{
99 | if(!_topScrollView){
100 | _topScrollView = [[UIScrollView alloc]init];
101 | [self.view addSubview:_topScrollView];
102 | }
103 | return _topScrollView;
104 | }
105 |
106 | @end
107 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoXibViewController/DemoXibViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoXibViewController.m
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/10.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import "DemoXibViewController.h"
10 | #import "DemoSystemBarViewController.h"
11 | @interface DemoXibViewController ()
12 | ///是否禁止pop操作
13 | @property(assign, nonatomic)BOOL disablePop;
14 | @end
15 |
16 | @implementation DemoXibViewController
17 |
18 | - (void)viewDidLoad {
19 | [super viewDidLoad];
20 |
21 | //设置导航栏标题
22 | self.title = @"ZXNavigationBar";
23 |
24 | //设置最右侧的Button的图片和点击回调
25 | [self zx_setRightBtnWithImgName:@"set_icon" clickedBlock:^(UIButton * _Nonnull btn) {
26 | NSLog(@"点击了最右侧的Button");
27 | }];
28 |
29 | //最左侧的按钮添加”返回“文字,当当前控制器不是第0个的时候,ZXNavigationBar会自动显示返回图片,且点击返回上一个控制器
30 | [self.zx_navLeftBtn setTitle:@"返回" forState:UIControlStateNormal];
31 |
32 | __weak typeof(self) weakSelf = self;
33 | self.zx_handlePopBlock = ^BOOL(ZXNavigationBarController * _Nonnull viewController, ZXNavPopBlockFrom popBlockFrom) {
34 | return !weakSelf.disablePop;
35 | };
36 | }
37 |
38 | #pragma mark - Actions
39 |
40 | #pragma mark 点击了设置背景色橙色
41 | - (IBAction)changeBacColorAction:(UISwitch *)sender {
42 | if(sender.on){
43 | self.zx_navBarBackgroundColor = [UIColor orangeColor];
44 | }else{
45 | self.zx_navBarBackgroundColor = [UIColor whiteColor];
46 | }
47 | }
48 |
49 | #pragma mark 点击了设置背景图片
50 | - (IBAction)setBacImageAction:(UISwitch *)sender {
51 | if(sender.on){
52 | self.zx_navBarBackgroundImage = [UIImage imageNamed:@"nav_bac"];
53 | }else{
54 | self.zx_navBarBackgroundImage = nil;
55 | }
56 | }
57 |
58 | #pragma mark 点击了设置TintColor黄色
59 | - (IBAction)ChangeTintColorAction:(UISwitch *)sender {
60 | if(sender.on){
61 | self.zx_navTintColor = [UIColor yellowColor];
62 | }else{
63 | self.zx_navTintColor = [UIColor blackColor];
64 | }
65 | }
66 |
67 | #pragma mark 点击了设置大小标题效果
68 | - (IBAction)setBigSubTitleAction:(UISwitch *)sender {
69 | if(sender.on){
70 | [self zx_setMultiTitle:@"ZXNavigationBar" subTitle:@"subTitle"];
71 | }else{
72 | self.title = @"ZXNavigationBar";
73 | }
74 | }
75 |
76 | #pragma mark 点击了设置StatusBar白色
77 | - (IBAction)changeStatusBarAction:(UISwitch *)sender {
78 | if(sender.on){
79 | self.zx_navStatusBarStyle = ZXNavStatusBarStyleLight;
80 | }else{
81 | self.zx_navStatusBarStyle = ZXNavStatusBarStyleDefault;
82 | }
83 | }
84 |
85 | #pragma mark 点击了设置两边Item大小为30
86 | - (IBAction)changeItemSizeAction:(UISwitch *)sender {
87 | if(sender.on){
88 | self.zx_navItemSize = 30;
89 | }else{
90 | self.zx_navItemSize = ZXNavDefalutItemSize;
91 | }
92 | }
93 |
94 | #pragma mark 点击了设置两边Item边距为0
95 | - (IBAction)changeItemMarginAction:(UISwitch *)sender {
96 | if(sender.on){
97 | self.zx_navItemMargin = 0;
98 | }else{
99 | self.zx_navItemMargin = ZXNavDefalutItemMargin;
100 | }
101 | }
102 |
103 | #pragma mark 点击了设置渐变背景
104 | - (IBAction)changeGradientBacAction:(UISwitch *)sender {
105 | if(sender.on){
106 | [self zx_setNavGradientBacFrom:[UIColor magentaColor] to:[UIColor cyanColor]];
107 | }else{
108 | [self zx_removeNavGradientBac];
109 | }
110 |
111 | }
112 |
113 | #pragma mark 点击了更换为系统的导航栏
114 | - (IBAction)changeSystemNavBarAction:(UISwitch *)sender {
115 | if(sender.on){
116 | self.zx_showSystemNavBar = YES;
117 | }else{
118 | self.zx_showSystemNavBar = NO;
119 | self.zx_hideBaseNavBar = NO;
120 | }
121 |
122 | }
123 |
124 | #pragma mark 点击了右侧显示两个Item
125 | - (IBAction)changeRightSubBtnAction:(UISwitch *)sender {
126 | if(sender.on){
127 | //设置自定义NavItemView
128 | self.zx_navSubRightBtn.zx_customView = [UISwitch new];
129 | }else{
130 | self.zx_navSubRightBtn.zx_customView = nil;
131 | }
132 | }
133 |
134 | - (IBAction)disPopAction:(UISwitch *)sender {
135 | self.disablePop = sender.on;
136 | }
137 |
138 | @end
139 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoListViewController/DemoListViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoListViewController.m
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/10.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import "DemoListViewController.h"
10 | #import "DemoXibViewController.h"
11 | #import "DemoWeiboHotViewController.h"
12 | #import "DemoCustomNavViewController.h"
13 | #import "DemoCustomTitleViewViewController.h"
14 | #import "DemoSystemBarViewController.h"
15 | #import "DemoFoldFrameViewController.h"
16 | #import "DemoFoldXibViewController.h"
17 | #import "DemoCompatibleScrollViewViewController.h"
18 | #import "DemoPublicSystemBarViewController.h"
19 | @interface DemoListViewController ()
20 | @property (strong, nonatomic) UITableView *tableView;
21 | @property (strong, nonatomic) NSArray *datas;
22 | @end
23 |
24 | @implementation DemoListViewController
25 |
26 | - (void)viewDidLoad {
27 | [super viewDidLoad];
28 | [self setUpNav];
29 | [self setUpViewAndData];
30 | }
31 |
32 | - (void)setUpNav{
33 | self.title = @"ZXNavigationBar";
34 | self.zx_navEnableSmoothFromSystemNavBar = YES;
35 | }
36 |
37 | - (void)setUpViewAndData{
38 | self.datas = @[@"ZXNavigationBar属性设置",@"仿微博热搜页面导航栏",@"可伸缩式导航栏(从Xib中设置tableView约束)",@"可伸缩式导航栏(通过Frame设置tableView约束)",@"自定义导航栏",@"自定义TitleView",@"跳转到使用系统导航栏的控制器",@"ScrollView与侧滑返回手势冲突处理"];
39 | self.tableView = [[UITableView alloc]init];
40 | [self.view addSubview:self.tableView];
41 | self.tableView.delegate = self;
42 | self.tableView.dataSource = self;
43 | }
44 |
45 |
46 | - (void)viewDidLayoutSubviews{
47 | [super viewDidLayoutSubviews];
48 | self.tableView.frame = CGRectMake(0, ZXNavBarHeight, self.view.frame.size.width, self.view.frame.size.height - ZXNavBarHeight);
49 | }
50 |
51 | #pragma mark - UITableViewDataSource & UITableViewDelegate
52 | - (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
53 | return self.datas.count;
54 | }
55 |
56 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
57 | UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
58 | cell.textLabel.text = self.datas[indexPath.row];
59 | return cell;
60 | }
61 |
62 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
63 | return 70;
64 | }
65 |
66 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
67 | [tableView deselectRowAtIndexPath:indexPath animated:NO];
68 | UIViewController *vc;
69 | switch (indexPath.row) {
70 | case 0:{
71 | //跳转到ZXNavigationBar属性设置
72 | vc = [[DemoXibViewController alloc]init];
73 | break;
74 | }
75 | case 1:{
76 | //仿微博热搜页面导航栏
77 | vc = [[DemoWeiboHotViewController alloc]init];
78 | break;
79 | }
80 | case 2:{
81 | //可伸缩式导航栏(从Xib中设置tableView约束)
82 | vc = [[DemoFoldXibViewController alloc]init];
83 | break;
84 | }
85 | case 3:{
86 | //可伸缩式导航栏(通过Frame设置tableView约束)
87 | vc = [[DemoFoldFrameViewController alloc]init];
88 | break;
89 | }
90 | case 4:{
91 | //自定义导航栏
92 | vc = [[DemoCustomNavViewController alloc]init];
93 | break;
94 | }
95 | case 5:{
96 | //自定义TitleView
97 | vc = [[DemoCustomTitleViewViewController alloc]init];
98 | break;
99 | }
100 | case 6:{
101 | //跳转到使用系统导航栏的控制器
102 | vc = [[DemoPublicSystemBarViewController alloc]init];
103 | break;
104 | }
105 | case 7:{
106 | //与ScrollView侧滑返回手势冲突处理
107 | vc = [[DemoCompatibleScrollViewViewController alloc]init];
108 | break;
109 | }
110 |
111 | default:
112 | break;
113 | }
114 | if(vc){
115 | vc.title = self.datas[indexPath.row];
116 | [self.navigationController pushViewController:vc animated:YES];
117 | }
118 | }
119 |
120 |
121 |
122 | @end
123 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoWeiboHotViewController/DemoWeiboHotViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoWeiboHotViewController.m
3 | // ZXNavigationBarDemo
4 | //
5 | // Created by 李兆祥 on 2020/3/12.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | //
8 |
9 | #import "DemoWeiboHotViewController.h"
10 | #import "UIView+ZXNavFrameExtension.h"
11 | #import "DemoSystemBarViewController.h"
12 | @interface DemoWeiboHotViewController()
13 | @property (strong, nonatomic) UITableView *tableView;
14 | @property (strong, nonatomic) NSArray *datas;
15 | @end
16 | @implementation DemoWeiboHotViewController
17 |
18 | - (void)viewDidLoad {
19 | [super viewDidLoad];
20 | [self setUpNav];
21 | [self setUpViewAndData];
22 | }
23 |
24 | - (void)setUpNav{
25 | //设置导航栏背景色RGB中Alpha为0
26 | self.zx_navBarBackgroundColorAlpha = 0;
27 | //左侧按钮添加”返回“文字
28 | [self.zx_navLeftBtn setTitle:@"返回" forState:UIControlStateNormal];
29 | //设置最右侧按钮的图片和点击事件
30 | __weak typeof(self) weakSelf = self;
31 | [self zx_setRightBtnWithImgName:@"right_more_icon" clickedBlock:^(ZXNavItemBtn * _Nonnull btn) {
32 | NSLog(@"点击了最右边的按钮");
33 | DemoSystemBarViewController *vc = [[DemoSystemBarViewController alloc]init];
34 | [weakSelf.navigationController pushViewController:vc animated:YES];
35 | }];
36 | self.zx_navEnableSmoothFromSystemNavBar = YES;
37 | [self setLightNav];
38 | }
39 |
40 | - (void)setUpViewAndData{
41 | self.datas = @[@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳",@"武汉加油,中国加油🇨🇳"];
42 | self.tableView = [[UITableView alloc]initWithFrame:CGRectZero style:UITableViewStyleGrouped];
43 | [self.view addSubview:self.tableView];
44 | self.tableView.delegate = self;
45 | self.tableView.dataSource = self;
46 | }
47 |
48 | - (void)viewDidLayoutSubviews{
49 | [super viewDidLayoutSubviews];
50 | self.tableView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
51 | }
52 |
53 | #pragma mark 设置导航栏为黑色
54 | - (void)setDarkNav{
55 | //设置导航栏文字标题和两侧按钮的颜色为黑色
56 | [self setZx_navTintColor:[UIColor blackColor]];
57 | //设置导航栏文字标题
58 | self.title = @"微博热搜";
59 | //隐藏分割线
60 | self.zx_navLineView.hidden = NO;
61 | //设置状态栏为黑色
62 | self.zx_navStatusBarStyle = ZXNavStatusBarStyleDefault;
63 | }
64 |
65 | #pragma mark 设置导航栏为白色
66 | - (void)setLightNav{
67 | //设置导航栏文字标题和两侧按钮的颜色为白色
68 | [self setZx_navTintColor:[UIColor whiteColor]];
69 | //设置导航栏文字标题
70 | self.title = @"";
71 | //显示分割线
72 | self.zx_navLineView.hidden = YES;
73 | //设置状态栏为白色
74 | self.zx_navStatusBarStyle = ZXNavStatusBarStyleLight;
75 | }
76 |
77 | #pragma mark - UIScrollViewDelegate
78 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView{
79 | [self zx_setNavTransparentGradientsWithScrollView:scrollView fullChangeHeight:100 changeLimitNavAlphe:0.7 transparentGradientsTransparentBlock:^{
80 | [self setLightNav];
81 | } transparentGradientsOpaqueBlock:^{
82 | [self setDarkNav];
83 | }];
84 | }
85 |
86 |
87 | #pragma mark - UITableViewDataSource & UITableViewDelegate
88 | - (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
89 | return self.datas.count;
90 | }
91 |
92 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
93 | UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
94 | cell.textLabel.text = self.datas[indexPath.row];
95 | return cell;
96 | }
97 |
98 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
99 | return 50;
100 | }
101 |
102 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
103 | [tableView deselectRowAtIndexPath:indexPath animated:NO];
104 | }
105 |
106 | - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
107 | UIImageView *headerImageView = [[UIImageView alloc]init];
108 | headerImageView.image = [UIImage imageNamed:@"weibo_hot_bac.jpg"];
109 | return headerImageView;
110 | }
111 | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
112 | return self.view.frame.size.width * 0.5;
113 | }
114 | @end
115 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoCustomTitleViewViewController/DemoCustomTitleView/DemoCustomTitleView.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 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarDefine.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavigationBarDefine.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/7.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #ifndef ZXNavigationBarDefine_h
11 | #define ZXNavigationBarDefine_h
12 | #define ZXNavDefalutBacColor [UIColor whiteColor]
13 | #define ZXNavDefalutTitleColor [UIColor blackColor]
14 | #define ZXNavDefalutLineColor [UIColor colorWithRed:220 / 255.0 green:220 / 255.0 blue:220 / 255.0 alpha:0.8]
15 | #define ZXNavDefalutItemTextColor [UIColor blackColor]
16 |
17 | #define ZXNavDefalutTitleSize 17
18 | #define ZXNavDefalutSubTitleSize 10
19 | #define ZXNavDefalutItemFontSize 15
20 |
21 | #define ZXNavDefalutItemSize 22
22 | #define ZXNavDefalutItemMargin 10
23 |
24 | #define ZXNavHistoryStackCellHeight 44
25 | #define ZXNavHistoryStackCellTitleX 16
26 | #define ZXNavHistoryStackViewWidth 250
27 | #define ZXNavHistoryStackViewItemMaxLength 6
28 | #define ZXNavHistoryStackViewStyleDarkBackgroundColor [UIColor colorWithRed:16 / 255.0 green:16 / 255.0 blue:16 / 255.0 alpha:1]
29 | #define ZXNavHistoryStackViewStyleDarkSelectedColor [UIColor colorWithRed:66 / 255.0 green:66 / 255.0 blue:66 / 255.0 alpha:1]
30 | #define ZXNavHistoryStackViewStyleLightBackgroundColor [UIColor colorWithRed:255.0 / 255.0 green:255.0 / 255.0 blue:255.0 / 255.0 alpha:1]
31 | #define ZXNavHistoryStackViewStyleLightSelectedColor [UIColor colorWithRed:225 / 255.0 green:225 / 255.0 blue:225 / 255.0 alpha:1]
32 |
33 | /**
34 | 获取主Window
35 |
36 | @return 主Window
37 | */
38 | #define ZXMainWindow ([UIApplication sharedApplication].keyWindow ?: [UIApplication sharedApplication].windows.firstObject)
39 |
40 | /**
41 | 获取是否是iPad设备
42 |
43 | @return 是否是iPad设备
44 | */
45 | #define ZXIsIPad ([[UIDevice currentDevice] userInterfaceIdiom]==UIUserInterfaceIdiomPad)
46 |
47 | /**
48 | 判断是否是刘海屏(全面屏iPad不算)
49 |
50 | @return 是否是刘海屏(全面屏iPad不算)
51 | */
52 | #define ZXIsBangScreen ({\
53 | int cFlag = 0;\
54 | if(ZXIsIPad){cFlag = 0;}\
55 | else if(@available(iOS 11.0, *)){\
56 | if(ZXMainWindow.safeAreaInsets.bottom > 0){\
57 | cFlag = 1;\
58 | }else{\
59 | cFlag = 0;\
60 | }\
61 | }else{\
62 | cFlag = 0;\
63 | }\
64 | cFlag;\
65 | })
66 |
67 | /**
68 | 是否是全面屏iPad
69 |
70 | @return 是否是全面屏iPad
71 | */
72 | #define ZXIsFullScreenIpad ({\
73 | int cFlag = 0;\
74 | if(@available(iOS 11.0, *)){\
75 | if(ZXMainWindow.safeAreaInsets.bottom > 0 && ZXIsIPad){\
76 | cFlag = 1;\
77 | }else{\
78 | cFlag = 0;\
79 | }\
80 | }else{\
81 | cFlag = 0;\
82 | }\
83 | cFlag;\
84 | })
85 |
86 | /**
87 | 判断手机是否是横屏
88 |
89 | @return 手机是否是横屏
90 | */
91 | #define ZXIsHorizontalScreen ([UIApplication sharedApplication].statusBarOrientation == UIDeviceOrientationLandscapeRight || [UIApplication sharedApplication].statusBarOrientation == UIDeviceOrientationLandscapeLeft)
92 |
93 | /**
94 | 获取屏幕宽度
95 |
96 | @return 屏幕宽度
97 | */
98 | #define ZXScreenWidth [UIScreen mainScreen].bounds.size.width
99 |
100 | /**
101 | 获取屏幕高度
102 |
103 | @return 屏幕高度
104 | */
105 | #define ZXScreenHeight [UIScreen mainScreen].bounds.size.height
106 |
107 | /**
108 | 获取导航栏高度(不包含状态栏高度)
109 |
110 | @return 导航栏高度(不包含状态栏高度)
111 | */
112 | #define ZXNavBarHeightNotIncludeStatusBar (ZXIsIPad ? 50 : 44)
113 |
114 |
115 | /**
116 | 获取iPhone设备状态栏高度
117 |
118 | @return iPhone设备状态栏高度
119 | */
120 | #define ZXIPhoneAppStatusBarHeight ({\
121 | int height = 0;\
122 | if(@available(iOS 13.0, *)){\
123 | height = [[UIApplication sharedApplication] statusBarFrame].size.height != 0 ? [[UIApplication sharedApplication] statusBarFrame].size.height : (ZXIsBangScreen ? 44 : 20);\
124 | }else{\
125 | height = (ZXIsBangScreen ? 44 : 20);\
126 | }\
127 | height;\
128 | })
129 |
130 | /**
131 | 获取状态栏高度
132 |
133 | @return 状态栏高度
134 | */
135 | //#define ZXAppStatusBarHeight [[UIApplication sharedApplication] statusBarFrame].size.height
136 | //适配iOS13以下系统开启热点或音视频时的导航栏(因为iOS13以下系统开启或音视频时状态栏会增高,从而导致计算出来的整个导航栏增高)
137 | #define ZXAppStatusBarHeight (ZXIsHorizontalScreen ? ZXRealAppStatusBarHeight : ZXIsFullScreenIpad ? ZXRealAppStatusBarHeight : ZXIPhoneAppStatusBarHeight)
138 |
139 |
140 | /**
141 | 获取真实状态栏高度
142 |
143 | @return 真实状态栏高度
144 | */
145 | #define ZXRealAppStatusBarHeight [[UIApplication sharedApplication] statusBarFrame].size.height
146 |
147 | /**
148 | 获取导航栏高度
149 |
150 | @return 导航栏高度
151 | */
152 | #define ZXNavBarHeight (ZXAppStatusBarHeight + ZXNavBarHeightNotIncludeStatusBar)
153 |
154 | /**
155 | 获取安全区域顶部高度
156 |
157 | @return 安全区域顶部高度
158 | */
159 | #define ZXSafeAreaTop ({\
160 | int height = 0;\
161 | if (@available(iOS 11.0, *)) {\
162 | height = ZXMainWindow.safeAreaInsets.top;\
163 | }else{\
164 | height = 0;\
165 | }\
166 | height;\
167 | })
168 |
169 | /**
170 | 获取安全区域底部高度
171 |
172 | @return 安全区域底部高度
173 | */
174 | #define ZXSafeAreaBottom ({\
175 | int height = 0;\
176 | if (@available(iOS 11.0, *)) {\
177 | height = ZXMainWindow.safeAreaInsets.bottom;\
178 | }else{\
179 | height = 0;\
180 | }\
181 | height;\
182 | })
183 |
184 | /**
185 | 获取横屏后左右安全距离
186 |
187 | @return 横屏后左右安全距离
188 | */
189 | #define ZXHorizontaledSafeArea ((ZXIsHorizontalScreen && ZXIsBangScreen)? ZXNavBarHeightNotIncludeStatusBar : 0)
190 |
191 | /**
192 | 属性过期标注
193 | */
194 | #define ZXNavigationBarDeprecated(DESCRIPTION) __attribute__((deprecated(DESCRIPTION)))
195 |
196 | #endif /* ZXNavigationBarDefine_h */
197 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarDefine.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavigationBarDefine.h
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/7.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #ifndef ZXNavigationBarDefine_h
11 | #define ZXNavigationBarDefine_h
12 | #define ZXNavDefalutBacColor [UIColor whiteColor]
13 | #define ZXNavDefalutTitleColor [UIColor blackColor]
14 | #define ZXNavDefalutLineColor [UIColor colorWithRed:220 / 255.0 green:220 / 255.0 blue:220 / 255.0 alpha:0.8]
15 | #define ZXNavDefalutItemTextColor [UIColor blackColor]
16 |
17 | #define ZXNavDefalutTitleSize 17
18 | #define ZXNavDefalutSubTitleSize 10
19 | #define ZXNavDefalutItemFontSize 15
20 |
21 | #define ZXNavDefalutItemSize 22
22 | #define ZXNavDefalutItemMargin 10
23 |
24 | #define ZXNavHistoryStackCellHeight 44
25 | #define ZXNavHistoryStackCellTitleX 16
26 | #define ZXNavHistoryStackViewWidth 250
27 | #define ZXNavHistoryStackViewItemMaxLength 6
28 | #define ZXNavHistoryStackViewStyleDarkBackgroundColor [UIColor colorWithRed:16 / 255.0 green:16 / 255.0 blue:16 / 255.0 alpha:1]
29 | #define ZXNavHistoryStackViewStyleDarkSelectedColor [UIColor colorWithRed:66 / 255.0 green:66 / 255.0 blue:66 / 255.0 alpha:1]
30 | #define ZXNavHistoryStackViewStyleLightBackgroundColor [UIColor colorWithRed:255.0 / 255.0 green:255.0 / 255.0 blue:255.0 / 255.0 alpha:1]
31 | #define ZXNavHistoryStackViewStyleLightSelectedColor [UIColor colorWithRed:225 / 255.0 green:225 / 255.0 blue:225 / 255.0 alpha:1]
32 |
33 | /**
34 | 获取主Window
35 |
36 | @return 主Window
37 | */
38 | #define ZXMainWindow ([UIApplication sharedApplication].keyWindow ?: [UIApplication sharedApplication].windows.firstObject)
39 |
40 | /**
41 | 获取是否是iPad设备
42 |
43 | @return 是否是iPad设备
44 | */
45 | #define ZXIsIPad ([[UIDevice currentDevice] userInterfaceIdiom]==UIUserInterfaceIdiomPad)
46 |
47 | /**
48 | 判断是否是刘海屏(全面屏iPad不算)
49 |
50 | @return 是否是刘海屏(全面屏iPad不算)
51 | */
52 | #define ZXIsBangScreen ({\
53 | int cFlag = 0;\
54 | if(ZXIsIPad){cFlag = 0;}\
55 | else if(@available(iOS 11.0, *)){\
56 | if(ZXMainWindow.safeAreaInsets.bottom > 0){\
57 | cFlag = 1;\
58 | }else{\
59 | cFlag = 0;\
60 | }\
61 | }else{\
62 | cFlag = 0;\
63 | }\
64 | cFlag;\
65 | })
66 |
67 | /**
68 | 是否是全面屏iPad
69 |
70 | @return 是否是全面屏iPad
71 | */
72 | #define ZXIsFullScreenIpad ({\
73 | int cFlag = 0;\
74 | if(@available(iOS 11.0, *)){\
75 | if(ZXMainWindow.safeAreaInsets.bottom > 0 && ZXIsIPad){\
76 | cFlag = 1;\
77 | }else{\
78 | cFlag = 0;\
79 | }\
80 | }else{\
81 | cFlag = 0;\
82 | }\
83 | cFlag;\
84 | })
85 |
86 | /**
87 | 判断手机是否是横屏
88 |
89 | @return 手机是否是横屏
90 | */
91 | #define ZXIsHorizontalScreen ([UIApplication sharedApplication].statusBarOrientation == UIDeviceOrientationLandscapeRight || [UIApplication sharedApplication].statusBarOrientation == UIDeviceOrientationLandscapeLeft)
92 |
93 | /**
94 | 获取屏幕宽度
95 |
96 | @return 屏幕宽度
97 | */
98 | #define ZXScreenWidth [UIScreen mainScreen].bounds.size.width
99 |
100 | /**
101 | 获取屏幕高度
102 |
103 | @return 屏幕高度
104 | */
105 | #define ZXScreenHeight [UIScreen mainScreen].bounds.size.height
106 |
107 | /**
108 | 获取导航栏高度(不包含状态栏高度)
109 |
110 | @return 导航栏高度(不包含状态栏高度)
111 | */
112 | #define ZXNavBarHeightNotIncludeStatusBar (ZXIsIPad ? 50 : 44)
113 |
114 |
115 | /**
116 | 获取iPhone设备状态栏高度
117 |
118 | @return iPhone设备状态栏高度
119 | */
120 | #define ZXIPhoneAppStatusBarHeight ({\
121 | int height = 0;\
122 | if(@available(iOS 13.0, *)){\
123 | height = [[UIApplication sharedApplication] statusBarFrame].size.height != 0 ? [[UIApplication sharedApplication] statusBarFrame].size.height : (ZXIsBangScreen ? 44 : 20);\
124 | }else{\
125 | height = (ZXIsBangScreen ? 44 : 20);\
126 | }\
127 | height;\
128 | })
129 |
130 | /**
131 | 获取状态栏高度
132 |
133 | @return 状态栏高度
134 | */
135 | //#define ZXAppStatusBarHeight [[UIApplication sharedApplication] statusBarFrame].size.height
136 | //适配iOS13以下系统开启热点或音视频时的导航栏(因为iOS13以下系统开启或音视频时状态栏会增高,从而导致计算出来的整个导航栏增高)
137 | #define ZXAppStatusBarHeight (ZXIsHorizontalScreen ? ZXRealAppStatusBarHeight : ZXIsFullScreenIpad ? ZXRealAppStatusBarHeight : ZXIPhoneAppStatusBarHeight)
138 |
139 |
140 | /**
141 | 获取真实状态栏高度
142 |
143 | @return 真实状态栏高度
144 | */
145 | #define ZXRealAppStatusBarHeight [[UIApplication sharedApplication] statusBarFrame].size.height
146 |
147 | /**
148 | 获取导航栏高度
149 |
150 | @return 导航栏高度
151 | */
152 | #define ZXNavBarHeight (ZXAppStatusBarHeight + ZXNavBarHeightNotIncludeStatusBar)
153 |
154 | /**
155 | 获取安全区域顶部高度
156 |
157 | @return 安全区域顶部高度
158 | */
159 | #define ZXSafeAreaTop ({\
160 | int height = 0;\
161 | if (@available(iOS 11.0, *)) {\
162 | height = ZXMainWindow.safeAreaInsets.top;\
163 | }else{\
164 | height = 0;\
165 | }\
166 | height;\
167 | })
168 |
169 | /**
170 | 获取安全区域底部高度
171 |
172 | @return 安全区域底部高度
173 | */
174 | #define ZXSafeAreaBottom ({\
175 | int height = 0;\
176 | if (@available(iOS 11.0, *)) {\
177 | height = ZXMainWindow.safeAreaInsets.bottom;\
178 | }else{\
179 | height = 0;\
180 | }\
181 | height;\
182 | })
183 |
184 | /**
185 | 获取横屏后左右安全距离
186 |
187 | @return 横屏后左右安全距离
188 | */
189 | #define ZXHorizontaledSafeArea ((ZXIsHorizontalScreen && ZXIsBangScreen)? ZXNavBarHeightNotIncludeStatusBar : 0)
190 |
191 | /**
192 | 属性过期标注
193 | */
194 | #define ZXNavigationBarDeprecated(DESCRIPTION) __attribute__((deprecated(DESCRIPTION)))
195 |
196 | #endif /* ZXNavigationBarDefine_h */
197 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/Demo/DemoCustomNavViewController/DemoCustomNav/DemoCustomNav.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavHistoryStackView/View/ZXNavHistoryStackContentView.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavHistoryStackContentView.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/12/22.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "ZXNavHistoryStackContentView.h"
11 | #import "ZXNavHistoryStackCell.h"
12 |
13 | #import "ZXNavigationBarDefine.h"
14 | #import "UIView+ZXNavFrameExtension.h"
15 |
16 | #import
17 | static NSString *historyStackViewCellReuseIdentifier = @"ZXNavHistoryStackCell";
18 | @interface ZXNavHistoryStackContentView()
19 | @property (strong, nonatomic) UIView *coverView;
20 | @property (assign, nonatomic) BOOL isShowed;
21 | @property (strong, nonatomic) ZXNavHistoryStackModel *selectedHistoryStackModel;
22 | @end
23 | @implementation ZXNavHistoryStackContentView
24 |
25 | #pragma mark - Init
26 | - (instancetype)initWithFrame:(CGRect)frame{
27 | self = [super initWithFrame:frame];
28 | if(self){
29 | [self setUp];
30 | }
31 | return self;
32 | }
33 |
34 | - (void)setUp{
35 | [self addSubview:self.coverView];
36 | [self addSubview:self.zx_historyStackView];
37 | self.zx_historyStackView.delegate = self;
38 | self.zx_historyStackView.dataSource = self;
39 | [self.zx_historyStackView registerClass:[ZXNavHistoryStackCell class] forCellWithReuseIdentifier:historyStackViewCellReuseIdentifier];
40 | self.coverView.userInteractionEnabled = YES;
41 | UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(coverViewTouch)];
42 | UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(coverViewTouch)];
43 | [self.coverView addGestureRecognizer:panGestureRecognizer];
44 | [self.coverView addGestureRecognizer:tapGestureRecognizer];
45 |
46 |
47 | [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(orientationDidChange:)name:UIDeviceOrientationDidChangeNotification object:nil];
48 | }
49 |
50 | - (void)layoutSubviews{
51 | [super layoutSubviews];
52 | self.frame = [UIScreen mainScreen].bounds;
53 | self.coverView.frame = self.frame;
54 | if(self.isShowed){
55 | [self updateHistoryStackViewFrameWithHide:NO];
56 | }
57 | }
58 |
59 | - (void)coverViewTouch{
60 | if(self.isShowed){
61 | [self zx_hide];
62 | }
63 | }
64 |
65 | - (instancetype)zx_show{
66 | [ZXMainWindow addSubview:self];
67 | [self updateHistoryStackViewFrameWithHide:YES];
68 | [UIView animateWithDuration:0.2 animations:^{
69 | self.coverView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.05];
70 | [self updateHistoryStackViewFrameWithHide:NO];
71 | }completion:^(BOOL finished) {
72 | self.isShowed = YES;
73 | }];
74 |
75 | return self;
76 | }
77 |
78 | - (void)zx_hide{
79 | self.isShowed = NO;
80 | [UIView animateWithDuration:0.15 animations:^{
81 | self.coverView.backgroundColor = [UIColor colorWithWhite:0 alpha:0];
82 | [self updateHistoryStackViewFrameWithHide:YES];
83 | }completion:^(BOOL finished) {
84 | [self removeFromSuperview];
85 | }];
86 | }
87 |
88 | - (void)updateHistoryStackViewFrameWithHide:(BOOL)isHide{
89 | if(isHide){
90 | self.zx_historyStackView.frame = CGRectMake(self.zx_historyStackViewLeft + 20, ZXAppStatusBarHeight + ZXNavHistoryStackCellHeight / 2, 0, 0);
91 | }else{
92 | self.zx_historyStackView.frame = CGRectMake(self.zx_historyStackViewLeft, ZXAppStatusBarHeight, ZXNavHistoryStackViewWidth, self.zx_historyStackArray.count * ZXNavHistoryStackCellHeight);
93 | }
94 | }
95 |
96 | #pragma mark - UICollectionViewDelegate
97 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
98 | return CGSizeMake(self.zx_historyStackView.frame.size.width, ZXNavHistoryStackCellHeight);
99 | }
100 |
101 | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
102 | ZXNavHistoryStackModel *historyStackModel = self.zx_historyStackArray[indexPath.row];
103 | [self doPopViewController:historyStackModel];
104 | }
105 |
106 | #pragma mark - UICollectionViewDataSource
107 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
108 | return self.zx_historyStackArray.count;
109 | }
110 |
111 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
112 | ZXNavHistoryStackCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:historyStackViewCellReuseIdentifier forIndexPath:indexPath];
113 | cell.historyStackViewStyle = self.zx_historyStackViewStyle;
114 | cell.historyStackModel = self.zx_historyStackArray[indexPath.row];
115 | return cell;
116 | }
117 |
118 | #pragma mark - Private
119 | - (void)handlePanGestureWithPoint:(CGPoint)point{
120 | if(point.x > CGRectGetMaxX(self.zx_historyStackView.frame) || point.y > CGRectGetMaxY(self.zx_historyStackView.frame)){
121 | if(self.selectedHistoryStackModel){
122 | self.selectedHistoryStackModel.isSelected = NO;
123 | self.selectedHistoryStackModel = nil;
124 | [self.zx_historyStackView reloadData];
125 | }
126 | }else{
127 | if(self.selectedHistoryStackModel){
128 | self.selectedHistoryStackModel.isSelected = NO;
129 | }
130 | NSIndexPath *indexPath = [self.zx_historyStackView indexPathForItemAtPoint:point];
131 | ZXNavHistoryStackModel *historyStackModel = self.zx_historyStackArray[indexPath.row];
132 | if(indexPath && !(self.selectedHistoryStackModel && self.selectedHistoryStackModel == historyStackModel)){
133 | historyStackModel.isSelected = YES;
134 | [self.zx_historyStackView reloadData];
135 | self.selectedHistoryStackModel = historyStackModel;
136 | if (@available(iOS 10.0, *)){
137 | UIImpactFeedbackGenerator *impactFeedbackGenerator = [[UIImpactFeedbackGenerator alloc]initWithStyle:UIImpactFeedbackStyleLight];
138 | [impactFeedbackGenerator impactOccurred];
139 | }
140 | }
141 | }
142 | }
143 |
144 | - (void)handlePanGestureEnd{
145 | [self doPopViewController:self.selectedHistoryStackModel];
146 | }
147 |
148 |
149 | - (void)doPopViewController:(ZXNavHistoryStackModel *)historyStackModel{
150 | if(historyStackModel && historyStackModel.viewController && historyStackModel.viewController.navigationController){
151 | [historyStackModel.viewController.navigationController popToViewController:historyStackModel.viewController animated:YES];
152 | [self zx_hide];
153 | }
154 | }
155 |
156 | - (void)orientationDidChange:(NSNotification *)sender{
157 | if(self.isShowed){
158 | [self zx_hide];
159 | }
160 | }
161 |
162 | #pragma mark - LazyLoad
163 | - (ZXNavHistoryStackView *)zx_historyStackView{
164 | if(!_zx_historyStackView){
165 | UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
166 | flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
167 | flowLayout.minimumInteritemSpacing = 0;
168 | flowLayout.minimumLineSpacing = 0;
169 | _zx_historyStackView = [[ZXNavHistoryStackView alloc]initWithFrame:CGRectZero collectionViewLayout:flowLayout];
170 | _zx_historyStackView.backgroundColor = [UIColor whiteColor];
171 | _zx_historyStackView.clipsToBounds = YES;
172 | _zx_historyStackView.layer.cornerRadius = 12;
173 | if(self.zx_historyStackViewStyle == ZXNavHistoryStackViewStyleLight){
174 | _zx_historyStackView.backgroundColor = ZXNavHistoryStackViewStyleLightBackgroundColor;
175 | }else{
176 | _zx_historyStackView.backgroundColor = ZXNavHistoryStackViewStyleDarkBackgroundColor;
177 | }
178 |
179 | }
180 | return _zx_historyStackView;
181 | }
182 |
183 | - (UIView *)coverView{
184 | if(!_coverView){
185 | _coverView = [[UIView alloc]init];
186 | }
187 | return _coverView;
188 | }
189 |
190 | - (void)setZx_historyStackArray:(NSMutableArray *)zx_historyStackArray{
191 | _zx_historyStackArray = zx_historyStackArray;
192 | if(zx_historyStackArray.count){
193 | ZXNavHistoryStackModel *firstHistoryStackModel = zx_historyStackArray.firstObject;
194 | ZXNavHistoryStackModel *lastHistoryStackModel = zx_historyStackArray.lastObject;
195 | firstHistoryStackModel.isSelected = YES;
196 | self.selectedHistoryStackModel = firstHistoryStackModel;
197 | lastHistoryStackModel.isLast = YES;
198 | }
199 | }
200 |
201 | - (void)setZx_historyStackViewStyle:(ZXNavHistoryStackViewStyle)zx_historyStackViewStyle{
202 | _zx_historyStackViewStyle = zx_historyStackViewStyle;
203 | [self.zx_historyStackView reloadData];
204 | }
205 |
206 | - (void)setZx_historyStackViewLeft:(CGFloat)zx_historyStackViewLeft{
207 | _zx_historyStackViewLeft = zx_historyStackViewLeft;
208 | self.zx_historyStackView.zx_x = zx_historyStackViewLeft;
209 | }
210 |
211 | - (void)dealloc{
212 | [[NSNotificationCenter defaultCenter]removeObserver:self];
213 | }
214 |
215 | @end
216 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavHistoryStackView/View/ZXNavHistoryStackContentView.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavHistoryStackContentView.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/12/22.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "ZXNavHistoryStackContentView.h"
11 | #import "ZXNavHistoryStackCell.h"
12 |
13 | #import "ZXNavigationBarDefine.h"
14 | #import "UIView+ZXNavFrameExtension.h"
15 |
16 | #import
17 | static NSString *historyStackViewCellReuseIdentifier = @"ZXNavHistoryStackCell";
18 | @interface ZXNavHistoryStackContentView()
19 | @property (strong, nonatomic) UIView *coverView;
20 | @property (assign, nonatomic) BOOL isShowed;
21 | @property (strong, nonatomic) ZXNavHistoryStackModel *selectedHistoryStackModel;
22 | @end
23 | @implementation ZXNavHistoryStackContentView
24 |
25 | #pragma mark - Init
26 | - (instancetype)initWithFrame:(CGRect)frame{
27 | self = [super initWithFrame:frame];
28 | if(self){
29 | [self setUp];
30 | }
31 | return self;
32 | }
33 |
34 | - (void)setUp{
35 | [self addSubview:self.coverView];
36 | [self addSubview:self.zx_historyStackView];
37 | self.zx_historyStackView.delegate = self;
38 | self.zx_historyStackView.dataSource = self;
39 | [self.zx_historyStackView registerClass:[ZXNavHistoryStackCell class] forCellWithReuseIdentifier:historyStackViewCellReuseIdentifier];
40 | self.coverView.userInteractionEnabled = YES;
41 | UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(coverViewTouch)];
42 | UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(coverViewTouch)];
43 | [self.coverView addGestureRecognizer:panGestureRecognizer];
44 | [self.coverView addGestureRecognizer:tapGestureRecognizer];
45 |
46 |
47 | [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(orientationDidChange:)name:UIDeviceOrientationDidChangeNotification object:nil];
48 | }
49 |
50 | - (void)layoutSubviews{
51 | [super layoutSubviews];
52 | self.frame = [UIScreen mainScreen].bounds;
53 | self.coverView.frame = self.frame;
54 | if(self.isShowed){
55 | [self updateHistoryStackViewFrameWithHide:NO];
56 | }
57 | }
58 |
59 | - (void)coverViewTouch{
60 | if(self.isShowed){
61 | [self zx_hide];
62 | }
63 | }
64 |
65 | - (instancetype)zx_show{
66 | [ZXMainWindow addSubview:self];
67 | [self updateHistoryStackViewFrameWithHide:YES];
68 | [UIView animateWithDuration:0.2 animations:^{
69 | self.coverView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.05];
70 | [self updateHistoryStackViewFrameWithHide:NO];
71 | }completion:^(BOOL finished) {
72 | self.isShowed = YES;
73 | }];
74 |
75 | return self;
76 | }
77 |
78 | - (void)zx_hide{
79 | self.isShowed = NO;
80 | [UIView animateWithDuration:0.15 animations:^{
81 | self.coverView.backgroundColor = [UIColor colorWithWhite:0 alpha:0];
82 | [self updateHistoryStackViewFrameWithHide:YES];
83 | }completion:^(BOOL finished) {
84 | [self removeFromSuperview];
85 | }];
86 | }
87 |
88 | - (void)updateHistoryStackViewFrameWithHide:(BOOL)isHide{
89 | if(isHide){
90 | self.zx_historyStackView.frame = CGRectMake(self.zx_historyStackViewLeft + 20, ZXAppStatusBarHeight + ZXNavHistoryStackCellHeight / 2, 0, 0);
91 | }else{
92 | self.zx_historyStackView.frame = CGRectMake(self.zx_historyStackViewLeft, ZXAppStatusBarHeight, ZXNavHistoryStackViewWidth, self.zx_historyStackArray.count * ZXNavHistoryStackCellHeight);
93 | }
94 | }
95 |
96 | #pragma mark - UICollectionViewDelegate
97 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
98 | return CGSizeMake(self.zx_historyStackView.frame.size.width, ZXNavHistoryStackCellHeight);
99 | }
100 |
101 | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
102 | ZXNavHistoryStackModel *historyStackModel = self.zx_historyStackArray[indexPath.row];
103 | [self doPopViewController:historyStackModel];
104 | }
105 |
106 | #pragma mark - UICollectionViewDataSource
107 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
108 | return self.zx_historyStackArray.count;
109 | }
110 |
111 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
112 | ZXNavHistoryStackCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:historyStackViewCellReuseIdentifier forIndexPath:indexPath];
113 | cell.historyStackViewStyle = self.zx_historyStackViewStyle;
114 | cell.historyStackModel = self.zx_historyStackArray[indexPath.row];
115 | return cell;
116 | }
117 |
118 | #pragma mark - Private
119 | - (void)handlePanGestureWithPoint:(CGPoint)point{
120 | if(point.x > CGRectGetMaxX(self.zx_historyStackView.frame) || point.y > CGRectGetMaxY(self.zx_historyStackView.frame)){
121 | if(self.selectedHistoryStackModel){
122 | self.selectedHistoryStackModel.isSelected = NO;
123 | self.selectedHistoryStackModel = nil;
124 | [self.zx_historyStackView reloadData];
125 | }
126 | }else{
127 | if(self.selectedHistoryStackModel){
128 | self.selectedHistoryStackModel.isSelected = NO;
129 | }
130 | NSIndexPath *indexPath = [self.zx_historyStackView indexPathForItemAtPoint:point];
131 | ZXNavHistoryStackModel *historyStackModel = self.zx_historyStackArray[indexPath.row];
132 | if(indexPath && !(self.selectedHistoryStackModel && self.selectedHistoryStackModel == historyStackModel)){
133 | historyStackModel.isSelected = YES;
134 | [self.zx_historyStackView reloadData];
135 | self.selectedHistoryStackModel = historyStackModel;
136 | if (@available(iOS 10.0, *)){
137 | UIImpactFeedbackGenerator *impactFeedbackGenerator = [[UIImpactFeedbackGenerator alloc]initWithStyle:UIImpactFeedbackStyleLight];
138 | [impactFeedbackGenerator impactOccurred];
139 | }
140 | }
141 | }
142 | }
143 |
144 | - (void)handlePanGestureEnd{
145 | [self doPopViewController:self.selectedHistoryStackModel];
146 | }
147 |
148 |
149 | - (void)doPopViewController:(ZXNavHistoryStackModel *)historyStackModel{
150 | if(historyStackModel && historyStackModel.viewController && historyStackModel.viewController.navigationController){
151 | [historyStackModel.viewController.navigationController popToViewController:historyStackModel.viewController animated:YES];
152 | [self zx_hide];
153 | }
154 | }
155 |
156 | - (void)orientationDidChange:(NSNotification *)sender{
157 | if(self.isShowed){
158 | [self zx_hide];
159 | }
160 | }
161 |
162 | #pragma mark - LazyLoad
163 | - (ZXNavHistoryStackView *)zx_historyStackView{
164 | if(!_zx_historyStackView){
165 | UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
166 | flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
167 | flowLayout.minimumInteritemSpacing = 0;
168 | flowLayout.minimumLineSpacing = 0;
169 | _zx_historyStackView = [[ZXNavHistoryStackView alloc]initWithFrame:CGRectZero collectionViewLayout:flowLayout];
170 | _zx_historyStackView.backgroundColor = [UIColor whiteColor];
171 | _zx_historyStackView.clipsToBounds = YES;
172 | _zx_historyStackView.layer.cornerRadius = 12;
173 | if(self.zx_historyStackViewStyle == ZXNavHistoryStackViewStyleLight){
174 | _zx_historyStackView.backgroundColor = ZXNavHistoryStackViewStyleLightBackgroundColor;
175 | }else{
176 | _zx_historyStackView.backgroundColor = ZXNavHistoryStackViewStyleDarkBackgroundColor;
177 | }
178 |
179 | }
180 | return _zx_historyStackView;
181 | }
182 |
183 | - (UIView *)coverView{
184 | if(!_coverView){
185 | _coverView = [[UIView alloc]init];
186 | }
187 | return _coverView;
188 | }
189 |
190 | - (void)setZx_historyStackArray:(NSMutableArray *)zx_historyStackArray{
191 | _zx_historyStackArray = zx_historyStackArray;
192 | if(zx_historyStackArray.count){
193 | ZXNavHistoryStackModel *firstHistoryStackModel = zx_historyStackArray.firstObject;
194 | ZXNavHistoryStackModel *lastHistoryStackModel = zx_historyStackArray.lastObject;
195 | firstHistoryStackModel.isSelected = YES;
196 | self.selectedHistoryStackModel = firstHistoryStackModel;
197 | lastHistoryStackModel.isLast = YES;
198 | }
199 | }
200 |
201 | - (void)setZx_historyStackViewStyle:(ZXNavHistoryStackViewStyle)zx_historyStackViewStyle{
202 | _zx_historyStackViewStyle = zx_historyStackViewStyle;
203 | [self.zx_historyStackView reloadData];
204 | }
205 |
206 | - (void)setZx_historyStackViewLeft:(CGFloat)zx_historyStackViewLeft{
207 | _zx_historyStackViewLeft = zx_historyStackViewLeft;
208 | self.zx_historyStackView.zx_x = zx_historyStackViewLeft;
209 | }
210 |
211 | - (void)dealloc{
212 | [[NSNotificationCenter defaultCenter]removeObserver:self];
213 | }
214 |
215 | @end
216 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarSubViews/ZXNavItemBtn.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavItemBtn.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/3/7.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "ZXNavItemBtn.h"
11 | #import "ZXNavigationBarDefine.h"
12 | #import "UIImage+ZXNavColorRender.h"
13 | #import "NSString+ZXNavCalcSizeExtension.h"
14 | #import "NSAttributedString+ZXNavCalcSizeExtension.h"
15 | @interface ZXNavItemBtn()
16 | ///NavItemBtn frame发生改变时的回调
17 | @property(copy, nonatomic)void(^zx_frameUpdateBlock)(CGRect frame);
18 | @end
19 | @implementation ZXNavItemBtn
20 | #pragma mark - Init
21 | - (instancetype)initWithCoder:(NSCoder *)coder{
22 | self = [super initWithCoder:coder];
23 | if(self){
24 | [self setUp];
25 | }
26 | return self;
27 | }
28 |
29 | - (void)awakeFromNib{
30 | [super awakeFromNib];
31 | [self setUp];
32 | }
33 |
34 | - (instancetype)initWithFrame:(CGRect)frame{
35 | self = [super initWithFrame:frame];
36 | if(self){
37 | [self setUp];
38 | }
39 | return self;
40 | }
41 |
42 | - (void)setUp{
43 | self.zx_fixWidth = -1;
44 | self.zx_fixHeight = -1;
45 | self.zx_fixMarginLeft = -1;
46 | self.zx_fixMarginRight = -1;
47 | self.zx_fixImageSize = CGSizeZero;
48 | }
49 |
50 | #pragma mark - Public
51 | - (void)zx_updateLayout{
52 | [self zx_layoutImageAndTitle];
53 | [self noticeUpdateFrame];
54 | }
55 |
56 | #pragma mark - Setter
57 | - (void)setTitle:(NSString *)title forState:(UIControlState)state{
58 | if(self.zx_customView && title && title.length){
59 | return;
60 | }
61 | [super setTitle:title forState:state];
62 | if(self.zx_tintColor){
63 | [self setTitleColor:self.zx_tintColor forState:state];
64 | }
65 | [self zx_layoutImageAndTitle];
66 | [self noticeUpdateFrame];
67 | }
68 |
69 | - (void)setAttributedTitle:(NSAttributedString *)title forState:(UIControlState)state{
70 | if(self.zx_customView && title && title.length){
71 | return;
72 | }
73 | [super setAttributedTitle:title forState:state];
74 | [self zx_layoutImageAndTitle];
75 | [self noticeUpdateFrame];
76 | }
77 |
78 | - (void)setImage:(UIImage *)image forState:(UIControlState)state{
79 | if(self.zx_customView && image){
80 | return;
81 | }
82 | if(self.zx_tintColor){
83 | image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
84 | }else{
85 | image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
86 | }
87 | [super setImage:image forState:state];
88 | if(!image){
89 | self.imageView.image = image;
90 | }
91 | [self zx_layoutImageAndTitle];
92 | [self noticeUpdateFrame];
93 | }
94 |
95 | - (void)setZx_tintColor:(UIColor *)zx_tintColor{
96 | _zx_tintColor = zx_tintColor;
97 | self.tintColor = zx_tintColor;
98 | [self resetImage];
99 | [self resetTitle];
100 | }
101 |
102 |
103 | - (void)setZx_imageColor:(UIColor *)zx_imageColor{
104 | _zx_imageColor = zx_imageColor;
105 | self.tintColor = zx_imageColor;
106 | [self resetImage];
107 | }
108 |
109 | - (void)setZx_disableAutoLayoutImageAndTitle:(BOOL )zx_disableAutoLayoutImageAndTitle{
110 | _zx_disableAutoLayoutImageAndTitle = zx_disableAutoLayoutImageAndTitle;
111 | [self zx_layoutImageAndTitle];
112 | [self noticeUpdateFrame];
113 | }
114 |
115 | - (void)setZx_fixWidth:(CGFloat)zx_fixWidth{
116 | _zx_fixWidth = zx_fixWidth;
117 | [self.superview setValue:@1 forKey:@"shouldRefLayout"];
118 | [self noticeUpdateFrame];
119 | }
120 |
121 | - (void)setZx_fixHeight:(CGFloat)zx_fixHeight{
122 | _zx_fixHeight = zx_fixHeight;
123 | [self.superview setValue:@1 forKey:@"shouldRefLayout"];
124 | [self noticeUpdateFrame];
125 | }
126 |
127 | - (void)setZx_fixMarginLeft:(CGFloat)zx_fixMarginLeft{
128 | _zx_fixMarginLeft = zx_fixMarginLeft;
129 | [self.superview setValue:@1 forKey:@"shouldRefLayout"];
130 | [self noticeUpdateFrame];
131 | }
132 |
133 | - (void)setZx_fixMarginRight:(CGFloat)zx_fixMarginRight{
134 | _zx_fixMarginRight = zx_fixMarginRight;
135 | [self.superview setValue:@1 forKey:@"shouldRefLayout"];
136 | [self noticeUpdateFrame];
137 | }
138 |
139 | - (void)setZx_fontSize:(CGFloat)zx_fontSize{
140 | _zx_fontSize = zx_fontSize;
141 | self.titleLabel.font = [UIFont systemFontOfSize:zx_fontSize];
142 | [self.superview setValue:@1 forKey:@"shouldRefLayout"];
143 | [self zx_layoutImageAndTitle];
144 | [self noticeUpdateFrame];
145 | }
146 |
147 | - (void)setZx_fixImageSize:(CGSize)zx_fixImageSize{
148 | _zx_fixImageSize = zx_fixImageSize;
149 | [self.superview setValue:@1 forKey:@"shouldRefLayout"];
150 | [self zx_layoutImageAndTitle];
151 | [self noticeUpdateFrame];
152 | }
153 |
154 | - (void)setZx_textAttachWidth:(CGFloat)zx_textAttachWidth{
155 | _zx_textAttachWidth = zx_textAttachWidth;
156 | [self.superview setValue:@1 forKey:@"shouldRefLayout"];
157 | [self zx_layoutImageAndTitle];
158 | [self noticeUpdateFrame];
159 | }
160 |
161 | - (void)setZx_textAttachHeight:(CGFloat)zx_textAttachHeight{
162 | _zx_textAttachHeight = zx_textAttachHeight;
163 | [self.superview setValue:@1 forKey:@"shouldRefLayout"];
164 | [self zx_layoutImageAndTitle];
165 | [self noticeUpdateFrame];
166 | }
167 |
168 | - (void)setZx_setCornerRadiusRounded:(BOOL)zx_setCornerRadiusRounded{
169 | _zx_setCornerRadiusRounded = zx_setCornerRadiusRounded;
170 | [self noticeUpdateFrame];
171 | }
172 |
173 | - (void)setZx_imageOffsetX:(CGFloat)zx_imageOffsetX{
174 | _zx_imageOffsetX = zx_imageOffsetX;
175 | [self zx_layoutImageAndTitle];
176 | }
177 |
178 | - (void)setZx_customView:(UIView *)zx_customView{
179 | if(!zx_customView){
180 | if([self.subviews containsObject:_zx_customView]){
181 | [_zx_customView removeFromSuperview];
182 | }
183 | _zx_customView = nil;
184 | [self noticeUpdateFrame];
185 | return;
186 | }
187 | _zx_customView = zx_customView;
188 | if(![self.subviews containsObject:zx_customView]){
189 | [self addSubview:zx_customView];
190 | }
191 | if(CGRectEqualToRect(zx_customView.frame, CGRectZero)){
192 | CGFloat customViewWidth = self.zx_fixWidth < 0 ? ZXNavDefalutItemSize : self.zx_fixWidth;
193 | CGFloat customViewHeight = self.zx_fixHeight < 0 ? ZXNavDefalutItemSize : self.zx_fixWidth;
194 | zx_customView.frame = CGRectMake(0, 0, customViewWidth, customViewHeight);
195 | }
196 | if(zx_customView.frame.size.width){
197 | self.zx_fixWidth = zx_customView.frame.size.width + zx_customView.frame.origin.x * 2;
198 | }
199 | if(zx_customView.frame.size.height){
200 | self.zx_fixHeight = zx_customView.frame.size.height + zx_customView.frame.origin.y * 2;
201 | }
202 | [self setImage:nil forState:UIControlStateNormal];
203 | [self setTitle:@"" forState:UIControlStateNormal];
204 | [self setAttributedTitle:nil forState:UIControlStateNormal];
205 | }
206 |
207 | #pragma mark - pirvate
208 | - (void)noticeUpdateFrame{
209 | if(self.zx_barItemBtnFrameUpdateBlock){
210 | self.zx_barItemBtnFrameUpdateBlock(self);
211 | }
212 | }
213 |
214 | - (void)layoutSubviews{
215 | [super layoutSubviews];
216 | [self zx_layoutImageAndTitle];
217 | }
218 |
219 | - (void)resetImage{
220 | BOOL isStateFocused = NO;
221 | if(@available(iOS 9.0, *)){
222 | isStateFocused = self.state == UIControlStateFocused;
223 | }
224 | if(self.zx_useTintColorOnlyInStateNormal || isStateFocused){
225 | [self setImage:[self imageForState:UIControlStateNormal] forState:UIControlStateNormal];
226 | }else{
227 | [self setImage:self.currentImage forState:self.state];
228 | }
229 | }
230 |
231 |
232 | - (void)resetTitle{
233 | BOOL isStateFocused = NO;
234 | if(@available(iOS 9.0, *)){
235 | isStateFocused = self.state == UIControlStateFocused;
236 | }
237 | if(self.zx_useTintColorOnlyInStateNormal || isStateFocused){
238 | [self setTitle:[self titleForState:UIControlStateNormal] forState:UIControlStateNormal];
239 | }else{
240 | [self setTitle:self.currentTitle forState:self.state];
241 | }
242 | }
243 |
244 | #pragma mark ButtonLayout
245 | - (void)zx_layoutImageAndTitle{
246 | if(self.zx_disableAutoLayoutImageAndTitle){
247 | return;
248 | }
249 | CGFloat btnw = 0;
250 | if(self.currentAttributedTitle){
251 | btnw = [self.currentAttributedTitle zx_getAttrRectWidthWithLimitH:self.frame.size.height fontSize:self.titleLabel.font.pointSize] + 5;
252 | }else{
253 | if(self.currentTitle && self.currentTitle.length){
254 | btnw = [self.currentTitle zx_getRectWidthWithLimitH:self.frame.size.height fontSize:self.titleLabel.font.pointSize] + 5;
255 | }
256 |
257 | }
258 | btnw += self.zx_textAttachWidth;
259 | if(self.imageView.image){
260 | BOOL useFixImageSize = NO;
261 | CGFloat imageHeight = self.frame.size.height;
262 | CGFloat imageWidth = self.frame.size.height;
263 | if(!CGSizeEqualToSize(self.zx_fixImageSize,CGSizeZero)){
264 | imageHeight = self.zx_fixImageSize.height;
265 | imageWidth = self.zx_fixImageSize.width;
266 | useFixImageSize = YES;
267 | }
268 | CGFloat imageViewX = 0;
269 | if(!(self.currentTitle.length || self.currentAttributedTitle.length) && useFixImageSize){
270 | imageViewX = (self.frame.size.width - imageWidth) / 2 + self.zx_imageOffsetX;
271 | }
272 | self.imageView.frame = CGRectMake(imageViewX, (self.frame.size.height - imageHeight) / 2, imageWidth, imageHeight);
273 | self.titleLabel.frame = CGRectMake(CGRectGetMaxX(self.imageView.frame), 0, btnw, self.frame.size.height);
274 | }else{
275 | self.imageView.frame = CGRectZero;
276 | self.titleLabel.frame = CGRectMake(0, 0, btnw, self.frame.size.height);
277 | }
278 | }
279 |
280 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
281 | [super touchesBegan:touches withEvent:event];
282 | if(self.zx_touchesBeganBlock){
283 | self.zx_touchesBeganBlock();
284 | }
285 | }
286 |
287 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
288 | [super touchesEnded:touches withEvent:event];
289 | if(self.zx_touchesEndBlock){
290 | self.zx_touchesEndBlock();
291 | }
292 | }
293 |
294 | @end
295 |
--------------------------------------------------------------------------------
/ZXNavigationBar/ZXNavigationBarNavigationController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavigationBarNavigationController.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/5/29.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "ZXNavigationBarNavigationController.h"
11 | #import
12 | #import "ZXNavigationBarController.h"
13 | #import "ZXNavigationBarTableViewController.h"
14 | @interface ZXNavigationBarNavigationController ()
15 | @property (assign, nonatomic) CGFloat touchBeginX;
16 | @property (assign, nonatomic) BOOL doingPopGesture;
17 | @property (strong, nonatomic, nullable) UIViewController *zx_topViewController;
18 | @property (strong, nonatomic) id orgInteractivePopGestureRecognizerDelegate;
19 | @end
20 |
21 | @implementation ZXNavigationBarNavigationController
22 |
23 | - (void)viewDidLoad {
24 | self.orgInteractivePopGestureRecognizerDelegate = self.interactivePopGestureRecognizer.delegate;
25 | [super viewDidLoad];
26 | self.delegate = self;
27 | self.zx_popGestureCoverRatio = 1;
28 | [self addFullScreenGesture];
29 | }
30 |
31 | #pragma mark - 重写父类pop和push相关方法
32 | - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
33 | if([viewController isKindOfClass:[ZXNavigationBarController class]]){
34 | self.navigationBarHidden = YES;
35 | }
36 | [self updateTopViewController:viewController];
37 | if(!self.zx_disableAutoHidesBottomBarWhenPushed){
38 | [viewController setHidesBottomBarWhenPushed:self.viewControllers.count >= 1];
39 | }
40 | [super pushViewController:viewController animated:animated];
41 | }
42 |
43 | - (UIViewController *)popViewControllerAnimated:(BOOL)animated{
44 | if(self.childViewControllers.count > 1 && !self.doingPopGesture){
45 | [self updateTopViewController:self.childViewControllers[self.childViewControllers.count - 2]];
46 | }
47 | return [super popViewControllerAnimated:animated];
48 | }
49 |
50 | - (NSArray *)popToRootViewControllerAnimated:(BOOL)animated{
51 | if(self.viewControllers.firstObject && !self.doingPopGesture){
52 | [self updateTopViewController:self.viewControllers.firstObject];
53 | }
54 | if(!self.zx_disableAutoHidesBottomBarWhenPushed && self.viewControllers.count > 1){
55 | self.topViewController.hidesBottomBarWhenPushed = NO;
56 | }
57 | return [super popToRootViewControllerAnimated:animated];
58 | }
59 |
60 | - (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated{
61 | if(viewController && !self.doingPopGesture){
62 | [self updateTopViewController:viewController];
63 | }
64 | return [super popToViewController:viewController animated:animated];
65 | }
66 |
67 | #pragma mark - public
68 | - (void)zx_disablePopGesture{
69 | if(self.zx_popGestureRecognizer){
70 | [self.view removeGestureRecognizer:self.zx_popGestureRecognizer];
71 | }
72 | }
73 |
74 | #pragma mark - Private
75 | #pragma mark 添加全屏手势
76 | - (void)addFullScreenGesture{
77 | self.interactivePopGestureRecognizer.enabled = NO;
78 | UIPanGestureRecognizer *popGestureRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handleNavigationTransition:)];
79 | popGestureRecognizer.delegate = self;
80 | [self.view addGestureRecognizer:popGestureRecognizer];
81 | _zx_popGestureRecognizer = popGestureRecognizer;
82 | }
83 |
84 | #pragma mark 处理pop手势
85 | - (void)handleNavigationTransition:(UIPanGestureRecognizer *)panGesture{
86 | if(self.zx_topViewController && !self.doingPopGesture){
87 | if([self.zx_topViewController isKindOfClass:[ZXNavigationBarTableViewController class]]){
88 | ZXNavigationBarTableViewController *topViewController = (ZXNavigationBarTableViewController *)self.zx_topViewController;
89 | if(topViewController.zx_handlePopBlock){
90 | BOOL shouldPop = topViewController.zx_handlePopBlock((ZXNavigationBarTableViewController *)self.zx_topViewController,ZXNavPopBlockFromPopGesture);
91 | if(!shouldPop){
92 | return;
93 | }
94 | }
95 | }else{
96 | ZXNavigationBarController *topViewController = (ZXNavigationBarController *)self.zx_topViewController;
97 | if(topViewController.zx_handlePopBlock){
98 | BOOL shouldPop = topViewController.zx_handlePopBlock((ZXNavigationBarController *)self.zx_topViewController,ZXNavPopBlockFromPopGesture);
99 | if(!shouldPop){
100 | return;
101 | }
102 | }
103 | }
104 |
105 | }
106 | if(self.zx_navHandlePopGestureBlock){
107 | BOOL shouldPop = self.zx_navHandlePopGestureBlock(self.zx_topViewController);
108 | if(!shouldPop){
109 | return;
110 | }
111 | }
112 | CGFloat panGestureX = [panGesture locationInView:self.view].x;
113 | self.doingPopGesture = YES;
114 | [self.orgInteractivePopGestureRecognizerDelegate performSelector:@selector(handleNavigationTransition:) withObject:panGesture];
115 | CGFloat popOffsetX = panGestureX - self.touchBeginX;
116 | if(self.zx_handleCustomPopGesture){
117 | if(panGesture.state == UIGestureRecognizerStateEnded){
118 | self.doingPopGesture = NO;
119 | if(popOffsetX > self.view.frame.size.width / 2){
120 | if(@available(iOS 10.0, *)){
121 |
122 | }else{
123 | self.zx_handleCustomPopGesture(self.zx_topViewController,1);
124 | }
125 | }else{
126 | if(@available(iOS 10.0, *)){
127 |
128 | }else{
129 | self.zx_handleCustomPopGesture(self.zx_topViewController,0);
130 | }
131 |
132 | }
133 | }else{
134 | if(popOffsetX >= 0){
135 | self.zx_handleCustomPopGesture(self.zx_topViewController,(popOffsetX / self.view.frame.size.width));
136 | }else{
137 | self.zx_handleCustomPopGesture(self.zx_topViewController,0);
138 | }
139 | }
140 | }
141 | }
142 |
143 | #pragma mark 更新栈顶控制器
144 | - (void)updateTopViewController:(UIViewController *)viewController{
145 | self.zx_topViewController = nil;
146 | if(viewController && ([viewController isKindOfClass:[ZXNavigationBarController class]] || [viewController isKindOfClass:[ZXNavigationBarTableViewController class]] )){
147 | if([viewController isKindOfClass:[ZXNavigationBarController class]]){
148 | self.zx_topViewController = (ZXNavigationBarController *)viewController;
149 | }else{
150 | self.zx_topViewController = (ZXNavigationBarTableViewController *)viewController;
151 | }
152 | }
153 | }
154 |
155 | #pragma mark - UIGestureRecognizerDelegate
156 | - (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer{
157 | if(gestureRecognizer != self.zx_popGestureRecognizer){
158 | return YES;
159 | }
160 | if ([[self valueForKey:@"_isTransitioning"] boolValue]) {
161 | return NO;
162 | }
163 | /* **********************************************/
164 | // Thanks to @forkingdog https://github.com/forkingdog/FDFullscreenPopGesture Respect!
165 | CGPoint translation = [gestureRecognizer translationInView:self.view];
166 | BOOL isLeftToRight = [UIApplication sharedApplication].userInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionLeftToRight;
167 | CGFloat multiplier = isLeftToRight ? 1 : - 1;
168 | if ((translation.x * multiplier) <= 0) {
169 | return NO;
170 | }
171 | /* **********************************************/
172 | CGFloat panGestureX = [gestureRecognizer locationInView:self.view].x;
173 | CGFloat coverW = self.zx_popGestureCoverRatio * self.view.frame.size.width;
174 | if(panGestureX > coverW){
175 | return NO;
176 | }
177 | self.touchBeginX = [gestureRecognizer locationInView:self.view].x;
178 | return self.childViewControllers.count != 1;
179 | }
180 |
181 | - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
182 | BOOL shouldRecognizeSimultaneously = NO;
183 | if(self.zx_popGestureShouldRecognizeSimultaneously){
184 | shouldRecognizeSimultaneously = self.zx_popGestureShouldRecognizeSimultaneously(otherGestureRecognizer);
185 | }
186 | return shouldRecognizeSimultaneously;
187 | }
188 |
189 | #pragma mark - UINavigationControllerDelegate
190 | - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
191 | UIViewController *topViewController = self.topViewController;
192 | if(topViewController){
193 | id transitionCoordinator = topViewController.transitionCoordinator;
194 | if(transitionCoordinator){
195 | if(@available(iOS 10.0, *)){
196 | [transitionCoordinator notifyWhenInteractionChangesUsingBlock:^(id context){
197 | if([context isCancelled]){
198 | if(self.zx_handleCustomPopGesture){
199 | self.zx_handleCustomPopGesture(self.zx_topViewController,0);
200 | }
201 |
202 | }else{
203 | if(self.zx_handleCustomPopGesture){
204 | self.zx_handleCustomPopGesture(self.zx_topViewController,1);
205 | }
206 | }
207 | }];
208 | }
209 | }
210 | }
211 | }
212 |
213 |
214 | #pragma mark - getter&setter
215 | - (void)setZx_disableFullScreenGesture:(BOOL)zx_disableFullScreenGesture{
216 | _zx_disableFullScreenGesture = zx_disableFullScreenGesture;
217 | if(zx_disableFullScreenGesture){
218 | self.zx_popGestureCoverRatio = 0.1;
219 | }else{
220 | self.zx_popGestureCoverRatio = 1;
221 | }
222 | }
223 |
224 |
225 | - (void)setZx_popGestureCoverRatio:(CGFloat)zx_popGestureCoverRatio{
226 | if(zx_popGestureCoverRatio > 1){
227 | _zx_popGestureCoverRatio = 1;
228 | }else if(zx_popGestureCoverRatio < 0){
229 | _zx_popGestureCoverRatio = 0;
230 | }else{
231 | _zx_popGestureCoverRatio = zx_popGestureCoverRatio;
232 | }
233 | }
234 | @end
235 |
--------------------------------------------------------------------------------
/ZXNavigationBarDemo/ZXNavigationBarDemo/ZXNavigationBar/ZXNavigationBarNavigationController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZXNavigationBarNavigationController.m
3 | // ZXNavigationBar
4 | //
5 | // Created by 李兆祥 on 2020/5/29.
6 | // Copyright © 2020 ZXLee. All rights reserved.
7 | // https://github.com/SmileZXLee/ZXNavigationBar
8 | // V1.4.1
9 |
10 | #import "ZXNavigationBarNavigationController.h"
11 | #import
12 | #import "ZXNavigationBarController.h"
13 | #import "ZXNavigationBarTableViewController.h"
14 | @interface ZXNavigationBarNavigationController ()
15 | @property (assign, nonatomic) CGFloat touchBeginX;
16 | @property (assign, nonatomic) BOOL doingPopGesture;
17 | @property (strong, nonatomic, nullable) UIViewController *zx_topViewController;
18 | @property (strong, nonatomic) id orgInteractivePopGestureRecognizerDelegate;
19 | @end
20 |
21 | @implementation ZXNavigationBarNavigationController
22 |
23 | - (void)viewDidLoad {
24 | self.orgInteractivePopGestureRecognizerDelegate = self.interactivePopGestureRecognizer.delegate;
25 | [super viewDidLoad];
26 | self.delegate = self;
27 | self.zx_popGestureCoverRatio = 1;
28 | [self addFullScreenGesture];
29 | }
30 |
31 | #pragma mark - 重写父类pop和push相关方法
32 | - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
33 | if([viewController isKindOfClass:[ZXNavigationBarController class]]){
34 | self.navigationBarHidden = YES;
35 | }
36 | [self updateTopViewController:viewController];
37 | if(!self.zx_disableAutoHidesBottomBarWhenPushed){
38 | [viewController setHidesBottomBarWhenPushed:self.viewControllers.count >= 1];
39 | }
40 | [super pushViewController:viewController animated:animated];
41 | }
42 |
43 | - (UIViewController *)popViewControllerAnimated:(BOOL)animated{
44 | if(self.childViewControllers.count > 1 && !self.doingPopGesture){
45 | [self updateTopViewController:self.childViewControllers[self.childViewControllers.count - 2]];
46 | }
47 | return [super popViewControllerAnimated:animated];
48 | }
49 |
50 | - (NSArray *)popToRootViewControllerAnimated:(BOOL)animated{
51 | if(self.viewControllers.firstObject && !self.doingPopGesture){
52 | [self updateTopViewController:self.viewControllers.firstObject];
53 | }
54 | if(!self.zx_disableAutoHidesBottomBarWhenPushed && self.viewControllers.count > 1){
55 | self.topViewController.hidesBottomBarWhenPushed = NO;
56 | }
57 | return [super popToRootViewControllerAnimated:animated];
58 | }
59 |
60 | - (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated{
61 | if(viewController && !self.doingPopGesture){
62 | [self updateTopViewController:viewController];
63 | }
64 | return [super popToViewController:viewController animated:animated];
65 | }
66 |
67 | #pragma mark - public
68 | - (void)zx_disablePopGesture{
69 | if(self.zx_popGestureRecognizer){
70 | [self.view removeGestureRecognizer:self.zx_popGestureRecognizer];
71 | }
72 | }
73 |
74 | #pragma mark - Private
75 | #pragma mark 添加全屏手势
76 | - (void)addFullScreenGesture{
77 | self.interactivePopGestureRecognizer.enabled = NO;
78 | UIPanGestureRecognizer *popGestureRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handleNavigationTransition:)];
79 | popGestureRecognizer.delegate = self;
80 | [self.view addGestureRecognizer:popGestureRecognizer];
81 | _zx_popGestureRecognizer = popGestureRecognizer;
82 | }
83 |
84 | #pragma mark 处理pop手势
85 | - (void)handleNavigationTransition:(UIPanGestureRecognizer *)panGesture{
86 | if(self.zx_topViewController && !self.doingPopGesture){
87 | if([self.zx_topViewController isKindOfClass:[ZXNavigationBarTableViewController class]]){
88 | ZXNavigationBarTableViewController *topViewController = (ZXNavigationBarTableViewController *)self.zx_topViewController;
89 | if(topViewController.zx_handlePopBlock){
90 | BOOL shouldPop = topViewController.zx_handlePopBlock((ZXNavigationBarTableViewController *)self.zx_topViewController,ZXNavPopBlockFromPopGesture);
91 | if(!shouldPop){
92 | return;
93 | }
94 | }
95 | }else{
96 | ZXNavigationBarController *topViewController = (ZXNavigationBarController *)self.zx_topViewController;
97 | if(topViewController.zx_handlePopBlock){
98 | BOOL shouldPop = topViewController.zx_handlePopBlock((ZXNavigationBarController *)self.zx_topViewController,ZXNavPopBlockFromPopGesture);
99 | if(!shouldPop){
100 | return;
101 | }
102 | }
103 | }
104 |
105 | }
106 | if(self.zx_navHandlePopGestureBlock){
107 | BOOL shouldPop = self.zx_navHandlePopGestureBlock(self.zx_topViewController);
108 | if(!shouldPop){
109 | return;
110 | }
111 | }
112 | CGFloat panGestureX = [panGesture locationInView:self.view].x;
113 | self.doingPopGesture = YES;
114 | [self.orgInteractivePopGestureRecognizerDelegate performSelector:@selector(handleNavigationTransition:) withObject:panGesture];
115 | CGFloat popOffsetX = panGestureX - self.touchBeginX;
116 | if(self.zx_handleCustomPopGesture){
117 | if(panGesture.state == UIGestureRecognizerStateEnded){
118 | self.doingPopGesture = NO;
119 | if(popOffsetX > self.view.frame.size.width / 2){
120 | if(@available(iOS 10.0, *)){
121 |
122 | }else{
123 | self.zx_handleCustomPopGesture(self.zx_topViewController,1);
124 | }
125 | }else{
126 | if(@available(iOS 10.0, *)){
127 |
128 | }else{
129 | self.zx_handleCustomPopGesture(self.zx_topViewController,0);
130 | }
131 |
132 | }
133 | }else{
134 | if(popOffsetX >= 0){
135 | self.zx_handleCustomPopGesture(self.zx_topViewController,(popOffsetX / self.view.frame.size.width));
136 | }else{
137 | self.zx_handleCustomPopGesture(self.zx_topViewController,0);
138 | }
139 | }
140 | }
141 | }
142 |
143 | #pragma mark 更新栈顶控制器
144 | - (void)updateTopViewController:(UIViewController *)viewController{
145 | self.zx_topViewController = nil;
146 | if(viewController && ([viewController isKindOfClass:[ZXNavigationBarController class]] || [viewController isKindOfClass:[ZXNavigationBarTableViewController class]] )){
147 | if([viewController isKindOfClass:[ZXNavigationBarController class]]){
148 | self.zx_topViewController = (ZXNavigationBarController *)viewController;
149 | }else{
150 | self.zx_topViewController = (ZXNavigationBarTableViewController *)viewController;
151 | }
152 | }
153 | }
154 |
155 | #pragma mark - UIGestureRecognizerDelegate
156 | - (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer{
157 | if(gestureRecognizer != self.zx_popGestureRecognizer){
158 | return YES;
159 | }
160 | if ([[self valueForKey:@"_isTransitioning"] boolValue]) {
161 | return NO;
162 | }
163 | /* **********************************************/
164 | // Thanks to @forkingdog https://github.com/forkingdog/FDFullscreenPopGesture Respect!
165 | CGPoint translation = [gestureRecognizer translationInView:self.view];
166 | BOOL isLeftToRight = [UIApplication sharedApplication].userInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionLeftToRight;
167 | CGFloat multiplier = isLeftToRight ? 1 : - 1;
168 | if ((translation.x * multiplier) <= 0) {
169 | return NO;
170 | }
171 | /* **********************************************/
172 | CGFloat panGestureX = [gestureRecognizer locationInView:self.view].x;
173 | CGFloat coverW = self.zx_popGestureCoverRatio * self.view.frame.size.width;
174 | if(panGestureX > coverW){
175 | return NO;
176 | }
177 | self.touchBeginX = [gestureRecognizer locationInView:self.view].x;
178 | return self.childViewControllers.count != 1;
179 | }
180 |
181 | - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
182 | BOOL shouldRecognizeSimultaneously = NO;
183 | if(self.zx_popGestureShouldRecognizeSimultaneously){
184 | shouldRecognizeSimultaneously = self.zx_popGestureShouldRecognizeSimultaneously(otherGestureRecognizer);
185 | }
186 | return shouldRecognizeSimultaneously;
187 | }
188 |
189 | #pragma mark - UINavigationControllerDelegate
190 | - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
191 | UIViewController *topViewController = self.topViewController;
192 | if(topViewController){
193 | id transitionCoordinator = topViewController.transitionCoordinator;
194 | if(transitionCoordinator){
195 | if(@available(iOS 10.0, *)){
196 | [transitionCoordinator notifyWhenInteractionChangesUsingBlock:^(id context){
197 | if([context isCancelled]){
198 | if(self.zx_handleCustomPopGesture){
199 | self.zx_handleCustomPopGesture(self.zx_topViewController,0);
200 | }
201 |
202 | }else{
203 | if(self.zx_handleCustomPopGesture){
204 | self.zx_handleCustomPopGesture(self.zx_topViewController,1);
205 | }
206 | }
207 | }];
208 | }
209 | }
210 | }
211 | }
212 |
213 |
214 | #pragma mark - getter&setter
215 | - (void)setZx_disableFullScreenGesture:(BOOL)zx_disableFullScreenGesture{
216 | _zx_disableFullScreenGesture = zx_disableFullScreenGesture;
217 | if(zx_disableFullScreenGesture){
218 | self.zx_popGestureCoverRatio = 0.1;
219 | }else{
220 | self.zx_popGestureCoverRatio = 1;
221 | }
222 | }
223 |
224 |
225 | - (void)setZx_popGestureCoverRatio:(CGFloat)zx_popGestureCoverRatio{
226 | if(zx_popGestureCoverRatio > 1){
227 | _zx_popGestureCoverRatio = 1;
228 | }else if(zx_popGestureCoverRatio < 0){
229 | _zx_popGestureCoverRatio = 0;
230 | }else{
231 | _zx_popGestureCoverRatio = zx_popGestureCoverRatio;
232 | }
233 | }
234 | @end
235 |
--------------------------------------------------------------------------------