@@ -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+
261324static 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
0 commit comments