I encountered such a scenario in a recent project. On a page pushed in, the navigation bar is set to be transparent, and the head view of the tableview group is controlled to hover over and display. Nav changes transparency with the tableview offset. Of course, such a requirement is not difficult, but if the current page continues to push a page that does not require such effects, a pit will appear when returning to the current page. The display of Nav is abrupt. Here is a direct solution...ps: Assume that page A needs to be set to transparent, page B is Apush and does not need to be set to transparent.
First write it in the viewDidload of the page where the navigation bar needs to be set to be transparent.
= @"Title"; [ setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; = [UIImage new]; = ; = 0; //Set the status bar [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]; //Set the title color = @{NSForegroundColorAttributeName : [UIColor clearColor]};
In scrollViewDidScroll proxy method
-(void)scrollViewDidScroll:(UIScrollView *)scrollView { CGFloat offset = ; //Set the size of (136) according to your needs CGFloat alpha = offset / 136; _barImageView.alpha = alpha; //Record the current transparency, which is required when returning to the current page _alpha = alpha; [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithFloat:alpha] forKey:@"_alpha"]; //Set the transparency of the title = @{NSForegroundColorAttributeName : [UIColor colorWithWhite:0 alpha:alpha]}; }
viewWillAppear, viewDidAppear, viewWillDisappear of the current page
-(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; = self; } -(void)viewDidAppear:(BOOL)animated { BOOL isGesturePop = [[[NSUserDefaults standardUserDefaults] objectForKey:@"isGesturePop"] boolValue]; if (!isGesturePop) { _barImageView.alpha = _alpha; = @{NSForegroundColorAttributeName : [UIColor colorWithWhite:0 alpha:_alpha]}; } [super viewDidAppear:animated]; } -(void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; = nil; = @{NSForegroundColorAttributeName : [UIColor blackColor]}; _barImageView.alpha = 1; [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:NO] forKey:@"isGesturePop"]; }
So what is needed to push the next page? We need to display normal nav on this page and disable the system gesture pop, and write a pop gesture by ourselves to facilitate us to get the offset when the pop slides. We used two classes when doing it, and the source code will be posted at the end.
UIGestureRecognizerDelegate must be followed and imported
Global variables
@property (nonatomic, strong) NavigationInteractiveTransition *navT;
viewDidLoad
= NO; UIGestureRecognizer *gesture = ; = NO; UIView *gestureView = ; UIPanGestureRecognizer *popRecognizer = [[UIPanGestureRecognizer alloc] init]; = self; = 1; [gestureView addGestureRecognizer:popRecognizer]; _navT = [[NavigationInteractiveTransition alloc] initWithViewController:]; [popRecognizer addTarget:_navT action:@selector(handleControllerPop:)];
UIGestureRecognizerDelegate proxy method gestureRecognizerShouldBegin
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { //Record whether the current yes is swiped back through gestures [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:YES] forKey:@"isGesturePop"]; /** * There are two conditions here that do not allow gesture execution, 1. The current controller is the root controller; 2. If the push and pop animation are being executed (private attributes) */ return != 1 && ![[ valueForKey:@"_isTransitioning"] boolValue]; }
Two source codes that need to be relied on
#import <UIKit/> @class UIViewController, UIPercentDrivenInteractiveTransition; @interface NavigationInteractiveTransition : NSObject <UINavigationControllerDelegate> - (instancetype)initWithViewController:(UIViewController *)vc; - (void)handleControllerPop:(UIPanGestureRecognizer *)recognizer; - (UIPercentDrivenInteractiveTransition *)interactivePopTransition; @end
#import "" #import "" @interface NavigationInteractiveTransition () @property (nonatomic, weak) UINavigationController *vc; @property (nonatomic, strong) UIPercentDrivenInteractiveTransition *interactivePopTransition; @property(nonatomic, strong) UIImageView *barImageView; @end @implementation NavigationInteractiveTransition - (instancetype)initWithViewController:(UIViewController *)vc { self = [super init]; if (self) { = (UINavigationController *)vc; = self; } return self; } /** * We use each Pan gesture operation of the user as a pop animation execution */ - (void)handleControllerPop:(UIPanGestureRecognizer *)recognizer { /** * interactivePopTransition is the object we mentioned in Method 2. We need to update its progress to control the process of Pop animation. We use the ratio of the position of our fingers in the view to the width of the view as its progress. */ CGFloat progress = [recognizer translationInView:].x / ; [ setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; = [UIImage new]; = ; CGFloat alpha = [[[NSUserDefaults standardUserDefaults] objectForKey:@"_alpha"] floatValue]; = 1 - progress > alpha ? alpha : 1 - progress; // NSLog(@"===progress==%.2f",progress); /** * Stabilize the progress interval, let it be between 0.0 (not completed) and 1.0 (completed) */ progress = MIN(1.0, MAX(0.0, progress)); if ( == UIGestureRecognizerStateBegan) { /** * The gesture starts and create a new monitoring object */ = [[UIPercentDrivenInteractiveTransition alloc] init]; /** * Tell the controller to start executing pop animation */ [ popViewControllerAnimated:YES]; } else if ( == UIGestureRecognizerStateChanged) { /** * Update gesture completion progress */ [ updateInteractiveTransition:progress]; } else if ( == UIGestureRecognizerStateEnded || == UIGestureRecognizerStateCancelled) { /** * If the progress is greater than half at the end of the gesture, then the pop operation is completed, otherwise it will be done again. */ if (progress > 0.5) { [ finishInteractiveTransition]; = 0;; } else { [ cancelInteractiveTransition]; } = nil; } } - (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC { /** * In Method 1, we determine that if the current Pop operation is being performed, we will return our customized Pop animation object. */ if (operation == UINavigationControllerOperationPop) return [[PopAnimation alloc] init]; return nil; } - (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController { /** * Method 2 will pass to your current animation object animationController. If it is our customized Pop animation object, then return the interactivePopTransition to monitor the animation completion degree. */ if ([animationController isKindOfClass:[PopAnimation class]]) return ; return nil; } @end
#import <Foundation/> #import <UIKit/> @interface PopAnimation : NSObject <UIViewControllerAnimatedTransitioning> @end
#import "" @interface PopAnimation () @property (nonatomic, strong) id <UIViewControllerContextTransitioning> transitionContext; @end @implementation PopAnimation - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext { //This method returns the time of the animation execution return 0.25; } /** * transitionContext You can see it as a tool that obtains objects related to a series of animation execution and notifies the system whether the animation is completed. */ - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext { /** * Get the controller from which the animation comes from */ UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; /** * Get the controller to which it was transferred */ UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; /** * Transition animation is an animation of two controller view time, and requires a containerView to act as a "stage" to allow the animation to be executed. */ UIView *containerView = [transitionContext containerView]; [containerView insertSubview: belowSubview:]; NSTimeInterval duration = [self transitionDuration:transitionContext]; /** * To perform animation, we move the view fromVC to the far right side of the screen */ [UIView animateWithDuration:duration animations:^{ = CGAffineTransformMakeTranslation([UIScreen mainScreen]., 0); }completion:^(BOOL finished) { /** * When your animation execution is completed, this method must be called, otherwise the system will think that any other operation of your operation is in the animation execution process. */ [transitionContext completeTransition:!]; }]; } - (void)animationDidStop:(CATransition *)anim finished:(BOOL)flag { [_transitionContext completeTransition:!_transitionContext.transitionWasCancelled]; } @end
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.