Skip to content

Commit

Permalink
新增仿iOS14导航栏历史堆栈;优化导航栏渐变过渡效果;导航栏左右按钮无内容时取消占位
Browse files Browse the repository at this point in the history
  • Loading branch information
SmileZXLee committed Dec 22, 2020
1 parent 9a54410 commit d23f34a
Show file tree
Hide file tree
Showing 77 changed files with 1,303 additions and 133 deletions.
2 changes: 1 addition & 1 deletion ZXNavigationBar/ZXNavigationBar.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by 李兆祥 on 2020/3/7.
// Copyright © 2020 ZXLee. All rights reserved.
// https://github.com/SmileZXLee/ZXNavigationBar
// V1.3.6
// V1.3.7

#import <UIKit/UIKit.h>
#import "ZXNavigationBarDefine.h"
Expand Down
37 changes: 21 additions & 16 deletions ZXNavigationBar/ZXNavigationBar.m
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by 李兆祥 on 2020/3/7.
// Copyright © 2020 ZXLee. All rights reserved.
// https://github.com/SmileZXLee/ZXNavigationBar
// V1.3.6
// V1.3.7

#import "ZXNavigationBar.h"
@interface ZXNavigationBar()
Expand Down Expand Up @@ -42,7 +42,7 @@ - (void)initNavBar{
self.backgroundColor = ZXNavDefalutBacColor;
_zx_itemSize = ZXNavDefalutItemSize;
_zx_itemMargin = ZXNavDefalutItemMargin;
_zx_lineViewHeight = 1;
_zx_lineViewHeight = 0.5;
ZXNavBacImageView *bacImageView = [[ZXNavBacImageView alloc]init];
bacImageView.clipsToBounds = YES;
bacImageView.contentMode = UIViewContentModeScaleAspectFill;
Expand Down Expand Up @@ -186,6 +186,11 @@ - (void)handleItemBtnFrame:(ZXNavItemBtn *)barItemBtn{
if(barItemBtn.zx_handleFrameBlock){
barItemBtn.frame = barItemBtn.zx_handleFrameBlock(barItemBtn.frame);
}
void(^frameUpdateBlock)(CGRect frame) = [barItemBtn valueForKey:@"zx_frameUpdateBlock"];
if(frameUpdateBlock){
frameUpdateBlock(barItemBtn.frame);
}

if(barItemBtn.zx_setCornerRadiusRounded){
barItemBtn.clipsToBounds = YES;
barItemBtn.layer.cornerRadius = barItemBtn.frame.size.height / 2;
Expand Down Expand Up @@ -238,40 +243,35 @@ - (void)relayoutSubviews{
CGSize leftBtnSize = CGSizeZero;
CGFloat leftBtnFinalHeight = [self getItemBtnHeight:self.zx_leftBtn];
CGFloat leftBtnFinalWidth = [self getItemBtnWidth:self.zx_leftBtn];
if((self.zx_leftBtn.zx_size.height == 0 && self.zx_leftBtn.zx_size.width == 0) || self.shouldRefLayout){
if(self.zx_leftBtn.currentImage || self.zx_leftBtn.currentTitle || self.zx_leftBtn.currentAttributedTitle || self.zx_leftBtn.zx_customView){
leftBtnSize = CGSizeMake(leftBtnFinalWidth, leftBtnFinalHeight);
}else{
leftBtnSize = self.zx_leftBtn.zx_size;
}
self.zx_leftBtn.frame = CGRectMake(self.zx_itemMargin + ZXHorizontaledSafeArea,(self.zx_height - leftBtnFinalHeight + centerOffSet) / 2, leftBtnSize.width, leftBtnSize.height);
[self handleItemBtnFrame:self.zx_leftBtn];
CGSize rightBtnSize = CGSizeZero;
CGFloat rightBtnW = 0;
CGFloat rightBtnFinalHeight = [self getItemBtnHeight:self.zx_rightBtn];
CGFloat rightBtnFinalWidth = [self getItemBtnWidth:self.zx_rightBtn];
if((self.zx_rightBtn.zx_size.height == 0 && self.zx_rightBtn.zx_size.width == 0 && self.zx_rightBtn.zx_x == 0) || self.shouldRefLayout){
if(self.zx_rightBtn.currentImage || self.zx_rightBtn.currentTitle || self.zx_rightBtn.currentAttributedTitle || self.zx_rightBtn.zx_customView){
rightBtnSize = CGSizeMake(rightBtnFinalWidth, rightBtnFinalHeight);
rightBtnW = self.zx_itemSize;
}else{
rightBtnSize = self.zx_rightBtn.zx_size;
rightBtnW = self.zx_rightBtn.zx_width;
}
self.zx_rightBtn.frame = CGRectMake(self.zx_width - self.zx_itemMargin - rightBtnSize.width - ZXHorizontaledSafeArea,(self.zx_height - rightBtnFinalHeight + centerOffSet) / 2, rightBtnSize.width,rightBtnSize.height);
[self handleItemBtnFrame:self.zx_rightBtn];
CGFloat subRightBtnFinalHeight = [self getItemBtnHeight:self.zx_subRightBtn];
CGFloat subRightBtnFinalWidth = [self getItemBtnWidth:self.zx_subRightBtn];
CGFloat subRightBtnRightMargin = self.zx_rightBtn.zx_width ? self.zx_itemMargin : 0;
if(!self.zx_subRightBtn.currentImage && !self.zx_subRightBtn.currentTitle && !self.zx_subRightBtn.currentAttributedTitle && !self.zx_subRightBtn.zx_customView){
self.zx_subRightBtn.frame = CGRectMake(CGRectGetMinX(self.zx_rightBtn.frame) - self.zx_itemMargin, self.zx_rightBtn.zx_y, 0, 0);
self.zx_subRightBtn.frame = CGRectMake(CGRectGetMinX(self.zx_rightBtn.frame) - subRightBtnRightMargin, self.zx_rightBtn.zx_y, 0, 0);
}else{
self.zx_subRightBtn.frame = CGRectMake(CGRectGetMinX(self.zx_rightBtn.frame) - self.zx_itemMargin - subRightBtnFinalWidth, (self.zx_height - subRightBtnFinalHeight + centerOffSet) / 2, subRightBtnFinalWidth, subRightBtnFinalHeight);;
self.zx_subRightBtn.frame = CGRectMake(CGRectGetMinX(self.zx_rightBtn.frame) - subRightBtnRightMargin - subRightBtnFinalWidth, (self.zx_height - subRightBtnFinalHeight + centerOffSet) / 2, subRightBtnFinalWidth, subRightBtnFinalHeight);;
}
[self handleItemBtnFrame:self.zx_subRightBtn];
CGFloat subLeftBtnFinalHeight = [self getItemBtnHeight:self.zx_subLeftBtn];
CGFloat subLeftBtnFinalWidth = [self getItemBtnWidth:self.zx_subLeftBtn];
CGFloat subLeftBtnLeftMargin = self.zx_leftBtn.zx_width ? self.zx_itemMargin : 0;
if(!self.zx_subLeftBtn.currentImage && !self.zx_subLeftBtn.currentTitle && !self.zx_subLeftBtn.currentAttributedTitle && !self.zx_subLeftBtn.zx_customView){
self.zx_subLeftBtn.frame = CGRectMake(CGRectGetMaxX(self.zx_leftBtn.frame) + self.zx_itemMargin, self.zx_leftBtn.zx_y, 0, 0);
self.zx_subLeftBtn.frame = CGRectMake(CGRectGetMaxX(self.zx_leftBtn.frame) + subLeftBtnLeftMargin, self.zx_leftBtn.zx_y, 0, 0);
}else{
self.zx_subLeftBtn.frame = CGRectMake(CGRectGetMaxX(self.zx_leftBtn.frame) + self.zx_itemMargin, (self.zx_height - subLeftBtnFinalHeight + centerOffSet) / 2, subLeftBtnFinalWidth, subLeftBtnFinalHeight);
self.zx_subLeftBtn.frame = CGRectMake(CGRectGetMaxX(self.zx_leftBtn.frame) + subLeftBtnLeftMargin, (self.zx_height - subLeftBtnFinalHeight + centerOffSet) / 2, subLeftBtnFinalWidth, subLeftBtnFinalHeight);
}
[self handleItemBtnFrame:self.zx_subLeftBtn];
CGFloat leftBtnFakeWidth = CGRectGetMaxX(self.zx_subLeftBtn.frame);
Expand Down Expand Up @@ -310,6 +310,9 @@ - (void)setZx_itemSize:(CGFloat)zx_itemSize{
_zx_itemSize = zx_itemSize;
self.shouldRefLayout = YES;
[self relayoutSubviews];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(CGFLOAT_MIN * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self relayoutSubviews];
});
}

- (void)setZx_itemMargin:(CGFloat)zx_itemMargin{
Expand All @@ -326,7 +329,9 @@ - (void)setZx_gradientLayer:(CAGradientLayer *)zx_gradientLayer{
if(_zx_gradientLayer){
[_zx_gradientLayer removeFromSuperlayer];
}
[self.layer insertSublayer:zx_gradientLayer atIndex:0];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(CGFLOAT_MIN * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.layer insertSublayer:zx_gradientLayer atIndex:0];
});
}
_zx_gradientLayer = zx_gradientLayer;
}
Expand Down
36 changes: 33 additions & 3 deletions ZXNavigationBar/ZXNavigationBarController.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
// Created by 李兆祥 on 2020/3/7.
// Copyright © 2020 ZXLee. All rights reserved.
// https://github.com/SmileZXLee/ZXNavigationBar
// V1.3.6
// V1.3.7

#import <UIKit/UIKit.h>
#import "UINavigationController+ZXNavBarAllHiddenExtension.h"
#import "ZXNavigationBarController+ZXNavSystemBarPopHandle.h"
#import "ZXNavigationBar.h"
#import "ZXNavigationBarNavigationController.h"
#import "ZXNavHistoryStackContentView.h"
NS_ASSUME_NONNULL_BEGIN
typedef enum {
ZXNavStatusBarStyleDefault = 0x01, // 状态栏颜色:黑色
Expand All @@ -20,7 +21,8 @@ typedef enum {

typedef enum {
ZXNavPopBlockFromBackButtonClick = 0x01, // 点击返回按钮触发pop
ZXNavPopBlockFromPopGesture = 0x02, // 返回手势触发pop
ZXNavPopBlockFromHistoryStack = 0x02, // 长按返回按钮显示历史堆栈触发pop
ZXNavPopBlockFromPopGesture = 0x03, // 返回手势触发pop
}ZXNavPopBlockFrom;

typedef void(^leftBtnClickedBlock) (ZXNavItemBtn *btn);
Expand Down Expand Up @@ -149,10 +151,12 @@ typedef void(^transparentGradientsOpaqueBlock) (void);
导航栏分割线View背景颜色
*/
@property (strong, nonatomic)UIColor *zx_navLineViewBackgroundColor;

/**
导航栏分割线的高度,默认为1
导航栏分割线的高度,默认为0.5
*/
@property (assign, nonatomic)CGFloat zx_navLineViewHeight;

/**
最左侧Button
*/
Expand Down Expand Up @@ -263,6 +267,32 @@ pop手势是否支持多层级的手势同时触发,默认为否。若设置
导航栏固定高度
*/
@property (assign, nonatomic)int zx_navFixHeight;

/**
导航栏历史堆栈视图
*/
@property(weak, nonatomic)ZXNavHistoryStackContentView *zx_navHistoryStackContentView;

/**
是否显示导航栏历史堆栈视图,默认为NO
*/
@property(assign, nonatomic)BOOL zx_showNavHistoryStackContentView;

/**
导航栏历史堆栈视图偏离的x值,默认为0(导航栏历史堆栈视图与屏幕左侧距离默认等于leftBtn与屏幕左侧距离,此属性用于自定义在此基础上增加或减少的水平位移)
*/
@property(assign, nonatomic)CGFloat zx_navHistoryStackContentViewOffsetX;

/**
导航栏历史堆栈视图Item展示最多的数量,默认为6个,超过6个显示由栈顶往下的6个
*/
@property(assign, nonatomic)long zx_navHistoryStackContentViewItemMaxLength;

/**
导航栏历史堆栈视图显示样式
*/
@property (assign, nonatomic) ZXNavHistoryStackViewStyle zx_navHistoryStackViewStyle;

/**
设置最左侧Button的图片和点击回调
Expand Down
81 changes: 79 additions & 2 deletions ZXNavigationBar/ZXNavigationBarController.m
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
// Created by 李兆祥 on 2020/3/7.
// Copyright © 2020 ZXLee. All rights reserved.
// https://github.com/SmileZXLee/ZXNavigationBar
// V1.3.6
// V1.3.7

#import "ZXNavigationBarController.h"
#import "ZXNavHistoryStackContentView.h"

#import <objc/message.h>
#import "UIImage+ZXNavBundleExtension.h"
Expand All @@ -25,6 +26,7 @@ @interface ZXNavigationBarController ()<UIGestureRecognizerDelegate>
@property(strong, nonatomic)CADisplayLink *displayLink;
@property(copy, nonatomic)foldingOffsetBlock offsetBlock;
@property(copy, nonatomic)foldCompletionBlock completionBlock;
@property(assign, nonatomic)BOOL isInLeftBtnTouchesBegan;
@property(strong, nonatomic)NSMutableArray<ZXXibTopConstraintModel *> *xibTopConstraintArr;
@end

Expand All @@ -34,6 +36,7 @@ @implementation ZXNavigationBarController
- (void)viewDidLoad {
[super viewDidLoad];
self.zx_navFixHeight = -1;
self.zx_navHistoryStackContentViewItemMaxLength = ZXNavHistoryStackViewItemMaxLength;
if(self.navigationController && !self.zx_hideBaseNavBar && !self.zx_disableAutoSetCustomNavBar){
[self initNavBar];
[self setAutoBack];
Expand Down Expand Up @@ -74,8 +77,25 @@ - (void)setAutoBack{
[self zx_leftClickedBlock:^(ZXNavItemBtn * _Nonnull btn) {
if(!(weakSelf.zx_handlePopBlock && !weakSelf.zx_handlePopBlock(weakSelf,ZXNavPopBlockFromBackButtonClick))){
[weakSelf.navigationController popViewControllerAnimated:YES];
[weakSelf zx_hideNavHistoryStackView];
}
}];

self.zx_navLeftBtn.userInteractionEnabled = YES;
self.zx_navLeftBtn.zx_touchesBeganBlock = ^{
weakSelf.isInLeftBtnTouchesBegan = YES;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if(weakSelf.isInLeftBtnTouchesBegan){
[weakSelf zx_showNavHistoryStackView];
}
weakSelf.isInLeftBtnTouchesBegan = NO;
});
};
self.zx_navLeftBtn.zx_touchesEndBlock = ^{
weakSelf.isInLeftBtnTouchesBegan = NO;
};
UIPanGestureRecognizer *leftBtnPanGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleLeftBtnPanGesture:)];
[self.zx_navLeftBtn addGestureRecognizer:leftBtnPanGestureRecognizer];
}
}

Expand Down Expand Up @@ -868,9 +888,51 @@ - (void)zx_setPopGestureCompatibleScrollView:(UIScrollView *)scrollView{
if(scrollView){
[self zx_setPopGestureCompatibleScrollViews:@[scrollView]];
}

}

#pragma mark 显示历史堆栈
-(void)zx_showNavHistoryStackView{
if(self.navigationController && self.zx_showNavHistoryStackContentView){
if(self.zx_handlePopBlock && !self.zx_handlePopBlock(self,ZXNavPopBlockFromHistoryStack)){
return;
}
ZXNavHistoryStackContentView *view = [[ZXNavHistoryStackContentView alloc]init];
NSMutableArray<ZXNavHistoryStackModel *> *historyStackArray = [NSMutableArray array];
NSMutableArray *viewControllersArr = [NSMutableArray arrayWithArray:self.navigationController.viewControllers];
if(viewControllersArr.count){
[viewControllersArr removeLastObject];
viewControllersArr = [NSMutableArray arrayWithArray:[[viewControllersArr reverseObjectEnumerator] allObjects]];
if(viewControllersArr.count > self.zx_navHistoryStackContentViewItemMaxLength){
[viewControllersArr removeObjectsInRange:NSMakeRange(self.zx_navHistoryStackContentViewItemMaxLength, viewControllersArr.count - self.zx_navHistoryStackContentViewItemMaxLength)];
}
for(UIViewController *viewController in viewControllersArr){

ZXNavHistoryStackModel *historyStackModel = [[ZXNavHistoryStackModel alloc]init];
NSString *title = viewController.title;
if([viewController isKindOfClass:[ZXNavigationBarController class]]){
title = ((ZXNavigationBarController *)viewController).zx_navTitleLabel.text;
}
historyStackModel.title = title;
historyStackModel.viewController = viewController;
[historyStackArray addObject:historyStackModel];
}
if(historyStackArray.count){
view.zx_historyStackArray = historyStackArray;
view.zx_historyStackViewLeft = self.zx_navLeftBtn.zx_x + self.zx_navHistoryStackContentViewOffsetX;
view.zx_historyStackViewStyle = self.zx_navHistoryStackViewStyle;
self.zx_navHistoryStackContentView = [view zx_show];
}
}
}
}

#pragma mark 隐藏历史堆栈
- (void)zx_hideNavHistoryStackView{
if(self.zx_navHistoryStackContentView){
[self.zx_navHistoryStackContentView zx_hide];
self.zx_navHistoryStackContentView = nil;
}
}

#pragma mark - Other
-(void)viewWillAppear:(BOOL)animated{
Expand Down Expand Up @@ -1015,4 +1077,19 @@ - (void)checkDoAutoSysBarAlpha{
self.doAutoSysBarAlphe = doAutoSysBarAlphe;
}

#pragma mark 处理返回按钮pan手势
- (void)handleLeftBtnPanGesture:(UIPanGestureRecognizer *)sender{
if(self.zx_navHistoryStackContentView){
CGPoint point = [sender locationInView:sender.view];
CGPoint convertedPoint = [self.zx_navHistoryStackContentView.zx_historyStackView convertPoint:point fromView:sender.view];
SEL sel = NSSelectorFromString(@"handlePanGestureWithPoint:");
((void (*)(id,SEL,CGPoint))objc_msgSend)(self.zx_navHistoryStackContentView, sel,convertedPoint);
if(sender.state == UIGestureRecognizerStateEnded){
sel = NSSelectorFromString(@"handlePanGestureEnd");
((void (*)(id,SEL))objc_msgSend)(self.zx_navHistoryStackContentView, sel);
}
}

}

@end
11 changes: 10 additions & 1 deletion ZXNavigationBar/ZXNavigationBarDefine.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by 李兆祥 on 2020/3/7.
// Copyright © 2020 ZXLee. All rights reserved.
// https://github.com/SmileZXLee/ZXNavigationBar
// V1.3.6
// V1.3.7

#ifndef ZXNavigationBarDefine_h
#define ZXNavigationBarDefine_h
Expand All @@ -21,6 +21,15 @@
#define ZXNavDefalutItemSize 22
#define ZXNavDefalutItemMargin 10

#define ZXNavHistoryStackCellHeight 44
#define ZXNavHistoryStackCellTitleX 16
#define ZXNavHistoryStackViewWidth 250
#define ZXNavHistoryStackViewItemMaxLength 6
#define ZXNavHistoryStackViewStyleDarkBackgroundColor [UIColor colorWithRed:16 / 255.0 green:16 / 255.0 blue:16 / 255.0 alpha:1]
#define ZXNavHistoryStackViewStyleDarkSelectedColor [UIColor colorWithRed:66 / 255.0 green:66 / 255.0 blue:66 / 255.0 alpha:1]
#define ZXNavHistoryStackViewStyleLightBackgroundColor [UIColor colorWithRed:255.0 / 255.0 green:255.0 / 255.0 blue:255.0 / 255.0 alpha:1]
#define ZXNavHistoryStackViewStyleLightSelectedColor [UIColor colorWithRed:225 / 255.0 green:225 / 255.0 blue:225 / 255.0 alpha:1]

/**
获取主Window
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by 李兆祥 on 2020/10/23.
// Copyright © 2020 ZXLee. All rights reserved.
// https://github.com/SmileZXLee/ZXNavigationBar
// V1.3.6
// V1.3.7

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by 李兆祥 on 2020/10/23.
// Copyright © 2020 ZXLee. All rights reserved.
// https://github.com/SmileZXLee/ZXNavigationBar
// V1.3.6
// V1.3.7

#import "NSAttributedString+ZXNavCalcSizeExtension.h"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by 李兆祥 on 2020/3/7.
// Copyright © 2020 ZXLee. All rights reserved.
// https://github.com/SmileZXLee/ZXNavigationBar
// V1.3.6
// V1.3.7

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by 李兆祥 on 2020/3/7.
// Copyright © 2020 ZXLee. All rights reserved.
// https://github.com/SmileZXLee/ZXNavigationBar
// V1.3.6
// V1.3.7

#import "NSString+ZXNavCalcSizeExtension.h"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by 李兆祥 on 2020/3/11.
// Copyright © 2020 ZXLee. All rights reserved.
// https://github.com/SmileZXLee/ZXNavigationBar
// V1.3.6
// V1.3.7

#import <UIKit/UIKit.h>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by 李兆祥 on 2020/3/11.
// Copyright © 2020 ZXLee. All rights reserved.
// https://github.com/SmileZXLee/ZXNavigationBar
// V1.3.6
// V1.3.7

#import "UIImage+ZXNavBundleExtension.h"
#import "ZXNavigationBar.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by 李兆祥 on 2020/3/10.
// Copyright © 2020 ZXLee. All rights reserved.
// https://github.com/SmileZXLee/ZXNavigationBar
// V1.3.6
// V1.3.7

#import <UIKit/UIKit.h>

Expand Down
Loading

0 comments on commit d23f34a

Please sign in to comment.