Skip to content

Commit 4264b4c

Browse files
committed
Merge commit '7050b616dc31b9d0e282d4f22ec3d13df61b992a'
2 parents 9ef9574 + 7050b61 commit 4264b4c

2 files changed

Lines changed: 111 additions & 0 deletions

File tree

QMUI/QMUIKit/UIKitExtensions/UINavigationController+NavigationBarTransition.m

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ @interface UIViewController (NavigationBarTransition)
2727
/// 是否要把真的navBar隐藏
2828
@property (nonatomic, assign) BOOL prefersNavigationBarBackgroundViewHidden;
2929

30+
/// 用于插入到fromVC和toVC的block
31+
typedef void (^navigationBarTransitionWillAppearInjectBlock)(UIViewController *viewController, BOOL animated);
32+
@property (nonatomic, copy) navigationBarTransitionWillAppearInjectBlock willAppearInjectBlock;
33+
3034
/// 添加假的navBar
3135
- (void)addTransitionNavigationBarIfNeeded;
3236

@@ -37,11 +41,15 @@ - (BOOL)respondCustomNavigationBarTransitionWhenPushAppearing;
3741
- (BOOL)respondCustomNavigationBarTransitionWhenPushDisappearing;
3842
- (BOOL)respondCustomNavigationBarTransitionWhenPopAppearing;
3943
- (BOOL)respondCustomNavigationBarTransitionWhenPopDisappearing;
44+
- (BOOL)respondCustomNavigationBarTransitionIfBarHiddenable;
45+
- (BOOL)respondCustomNavigationBarTransitionWithBarHiddenState;
4046

4147
- (BOOL)canCustomNavigationBarTransitionWhenPushAppearing;
4248
- (BOOL)canCustomNavigationBarTransitionWhenPushDisappearing;
4349
- (BOOL)canCustomNavigationBarTransitionWhenPopAppearing;
4450
- (BOOL)canCustomNavigationBarTransitionWhenPopDisappearing;
51+
- (BOOL)canCustomNavigationBarTransitionIfBarHiddenable;
52+
- (BOOL)canCustomNavigationBarTransitionWithBarHiddenState;
4553

4654
@end
4755

@@ -53,11 +61,28 @@ + (void)load {
5361
dispatch_once(&onceToken, ^{
5462
Class cls = [self class];
5563
ReplaceMethod(cls, @selector(viewWillLayoutSubviews), @selector(NavigationBarTransition_viewWillLayoutSubviews));
64+
ReplaceMethod(cls, @selector(viewWillAppear:), @selector(NavigationBarTransition_viewWillAppear:));
5665
ReplaceMethod(cls, @selector(viewDidAppear:), @selector(NavigationBarTransition_viewDidAppear:));
5766
ReplaceMethod(cls, @selector(viewDidDisappear:), @selector(NavigationBarTransition_viewDidDisappear:));
5867
});
5968
}
6069

70+
- (navigationBarTransitionWillAppearInjectBlock)willAppearInjectBlock {
71+
return objc_getAssociatedObject(self, _cmd);
72+
}
73+
74+
- (void)setWillAppearInjectBlock:(navigationBarTransitionWillAppearInjectBlock)willAppearInjectBlock {
75+
objc_setAssociatedObject(self, @selector(willAppearInjectBlock), willAppearInjectBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
76+
}
77+
78+
- (void)NavigationBarTransition_viewWillAppear:(BOOL)animated {
79+
[self NavigationBarTransition_viewWillAppear:animated];
80+
81+
if (self.willAppearInjectBlock) {
82+
self.willAppearInjectBlock(self, animated);
83+
}
84+
}
85+
6186
- (void)NavigationBarTransition_viewDidAppear:(BOOL)animated {
6287
if (self.transitionNavigationBar) {
6388
// 回到界面的时候,把假的navBar去掉并且还原老的navBar
@@ -224,6 +249,28 @@ - (BOOL)respondCustomNavigationBarTransitionWhenPopDisappearing {
224249
return respondPopDisappearing;
225250
}
226251

252+
- (BOOL)respondCustomNavigationBarTransitionIfBarHiddenable {
253+
BOOL respondIfBarHiddenable = NO;
254+
if ([self qmui_respondQMUINavigationControllerDelegate]) {
255+
UIViewController<QMUINavigationControllerDelegate> *vc = (UIViewController<QMUINavigationControllerDelegate> *)self;
256+
if ([vc respondsToSelector:@selector(shouldCustomNavigationBarTransitionIfBarHiddenable)]) {
257+
respondIfBarHiddenable = YES;
258+
}
259+
}
260+
return respondIfBarHiddenable;
261+
}
262+
263+
- (BOOL)respondCustomNavigationBarTransitionWithBarHiddenState {
264+
BOOL respondWithBarHiddenState = NO;
265+
if ([self qmui_respondQMUINavigationControllerDelegate]) {
266+
UIViewController<QMUINavigationControllerDelegate> *vc = (UIViewController<QMUINavigationControllerDelegate> *)self;
267+
if ([vc respondsToSelector:@selector(shouldCustomNavigationBarTransitionWithBarHiddenState)]) {
268+
respondWithBarHiddenState = YES;
269+
}
270+
}
271+
return respondWithBarHiddenState;
272+
}
273+
227274
// 该 viewController 实现自定义 navBar 动画的协议的返回值
228275

229276
- (BOOL)canCustomNavigationBarTransitionWhenPushAppearing {
@@ -258,6 +305,22 @@ - (BOOL)canCustomNavigationBarTransitionWhenPopDisappearing {
258305
return NO;
259306
}
260307

308+
- (BOOL)canCustomNavigationBarTransitionIfBarHiddenable {
309+
if ([self respondCustomNavigationBarTransitionIfBarHiddenable]) {
310+
UIViewController<QMUINavigationControllerDelegate> *vc = (UIViewController<QMUINavigationControllerDelegate> *)self;
311+
return [vc shouldCustomNavigationBarTransitionIfBarHiddenable];
312+
}
313+
return NO;
314+
}
315+
316+
-(BOOL)canCustomNavigationBarTransitionWithBarHiddenState {
317+
if ([self respondCustomNavigationBarTransitionWithBarHiddenState]) {
318+
UIViewController<QMUINavigationControllerDelegate> *vc = (UIViewController<QMUINavigationControllerDelegate> *)self;
319+
return [vc shouldCustomNavigationBarTransitionWithBarHiddenState];
320+
}
321+
return NO;
322+
}
323+
261324
static char lockTransitionNavigationBarKey;
262325

263326
- (BOOL)lockTransitionNavigationBar {
@@ -310,6 +373,7 @@ - (void)NavigationBarTransition_pushViewController:(UIViewController *)viewContr
310373
if (!disappearingViewController) {
311374
return [self NavigationBarTransition_pushViewController:viewController animated:animated];
312375
}
376+
313377
BOOL shouldCustomNavigationBarTransition = NO;
314378
if ([disappearingViewController canCustomNavigationBarTransitionWhenPushDisappearing]) {
315379
shouldCustomNavigationBarTransition = YES;
@@ -321,16 +385,49 @@ - (void)NavigationBarTransition_pushViewController:(UIViewController *)viewContr
321385
[disappearingViewController addTransitionNavigationBarIfNeeded];
322386
disappearingViewController.prefersNavigationBarBackgroundViewHidden = YES;
323387
}
388+
389+
// tq:这是为了兼容全屏状态下的效果,如果原来的"页面A"是 disappearingViewController ,将显示的"页面B"是 appearingViewController ,则:
390+
// 当A或B是允许全屏的vc,那么A和B都需要插入 Block 来等下次 viewWillAppear 改变 NavBar 的状态,以防回退旧的页面 bar 为空。
391+
if ([viewController canCustomNavigationBarTransitionIfBarHiddenable] || [disappearingViewController canCustomNavigationBarTransitionIfBarHiddenable]) {
392+
[self setupNavigationBarAppearanceWithViewController:viewController];
393+
}
394+
324395
return [self NavigationBarTransition_pushViewController:viewController animated:animated];
325396
}
326397

398+
- (void)setupNavigationBarAppearanceWithViewController:(UIViewController *)viewController{
399+
__weak typeof(self) weakSelf = self;
400+
navigationBarTransitionWillAppearInjectBlock block = ^(UIViewController *viewController, BOOL animated) {
401+
__strong typeof(weakSelf) strongSelf = weakSelf;
402+
403+
if (strongSelf) {
404+
if ([viewController canCustomNavigationBarTransitionWithBarHiddenState]) {
405+
[strongSelf setNavigationBarHidden:YES animated:animated];
406+
} else {
407+
[strongSelf setNavigationBarHidden:NO animated:animated];
408+
}
409+
}
410+
};
411+
412+
if (!viewController.willAppearInjectBlock) {
413+
viewController.willAppearInjectBlock = block;
414+
}
415+
416+
// 如果是进入新的vc,需要把旧的 vc 也加上该 block。
417+
UIViewController *disappearingViewController = self.viewControllers.lastObject;
418+
if (!disappearingViewController.willAppearInjectBlock) {
419+
disappearingViewController.willAppearInjectBlock = block;
420+
}
421+
}
422+
327423
- (UIViewController *)NavigationBarTransition_popViewControllerAnimated:(BOOL)animated {
328424
UIViewController *disappearingViewController = self.viewControllers.lastObject;
329425
UIViewController *appearingViewController = self.viewControllers.count >= 2 ? self.viewControllers[self.viewControllers.count - 2] : nil;
330426
if (!disappearingViewController) {
331427
return [self NavigationBarTransition_popViewControllerAnimated:animated];
332428
}
333429
[self handlePopViewControllerNavigationBarTransitionWithDisappearViewController:disappearingViewController appearViewController:appearingViewController];
430+
334431
return [self NavigationBarTransition_popViewControllerAnimated:animated];
335432
}
336433

QMUI/QMUIKit/UIMainFrame/QMUINavigationController.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,20 @@
6161
*/
6262
- (BOOL)shouldCustomNavigationBarTransitionWhenPopDisappearing;
6363

64+
/**
65+
* 当前导航栏是否具备全屏(隐藏navBar)的能力,默认返回NO。<br/>
66+
* 因为默认的全屏状态(隐藏navigationBar)下,手势返回时 toViewController 的 navigationBar 会缺失,需要设置此值用自定义的 pushViewController:animate: 来解决。
67+
* @see UINavigationController+NavigationBarTransition.h
68+
*/
69+
- (BOOL)shouldCustomNavigationBarTransitionIfBarHiddenable;
70+
71+
/**
72+
* 当前导航栏是否处于全屏状态,如果是则返回YES,默认返回NO。<br/>
73+
* 该属性用于判断如果在 popViewController 的时候如果 toViewController 是处于全屏的则不改变它的状态。
74+
* @see UINavigationController+NavigationBarTransition.h
75+
*/
76+
- (BOOL)shouldCustomNavigationBarTransitionWithBarHiddenState;
77+
6478
@end
6579

6680

0 commit comments

Comments
 (0)