https://github.com/ltebean/LTNavigationBar *navBar酷炫
http://www.jianshu.com/p/b2585c37e14b
http://www.jianshu.com/p/31f177158c9e *
返回至某个VC
for (UIViewController *controller in self.navigationController.viewControllers) {
if ([controller isKindOfClass:[AViewController class]]) {
AViewController *A =(AViewController *)controller;
[self.navigationController popToViewController:A animated:YES];
}
}
获取当前导航控制器
- (UIViewController *)currentViewController
{
UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
UIViewController *vc = keyWindow.rootViewController;
while (vc.presentedViewController)
{
vc = vc.presentedViewController;
if ([vc isKindOfClass:[UINavigationController class]])
{
vc = [(UINavigationController *)vc visibleViewController];
}
else if ([vc isKindOfClass:[UITabBarController class]])
{
vc = [(UITabBarController *)vc selectedViewController];
}
}
return vc;
}
- (UINavigationController *)currentNavigationController
{
return [self currentViewController].navigationController;
}
毛玻璃、动态隐藏
https://www.jianshu.com/p/b2585c37e14b
判断当前VC是push还是present的方式显示的
NSArray *viewcontrollers=self.navigationController.viewControllers;
if (viewcontrollers.count > 1)
{
if ([viewcontrollers objectAtIndex:viewcontrollers.count - 1] == self)
{
//push方式
[self.navigationController popViewControllerAnimated:YES];
}
}
else
{
//present方式
[self dismissViewControllerAnimated:YES completion:nil];
}
获取当前控制器(不管是push还是present方式)
- (UIViewController *)getVisibleViewControllerFrom:(UIViewController*)vc {
if ([vc isKindOfClass:[UINavigationController class]]) {
return [self getVisibleViewControllerFrom:[((UINavigationController*) vc) visibleViewController]];
}else if ([vc isKindOfClass:[UITabBarController class]]){
return [self getVisibleViewControllerFrom:[((UITabBarController*) vc) selectedViewController]];
} else {
if (vc.presentedViewController) {
return [self getVisibleViewControllerFrom:vc.presentedViewController];
} else {
return vc;
}
}
}
+ (UIViewController *)jsd_getCurrentViewController{
UIViewController* currentViewController = [self jsd_getRootViewController];
BOOL runLoopFind = YES;
while (runLoopFind) {
if (currentViewController.presentedViewController) {
currentViewController = currentViewController.presentedViewController;
} else if ([currentViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController* navigationController = (UINavigationController* )currentViewController;
currentViewController = [navigationController.childViewControllers lastObject];
} else if ([currentViewController isKindOfClass:[UITabBarController class]]) {
UITabBarController* tabBarController = (UITabBarController* )currentViewController;
currentViewController = tabBarController.selectedViewController;
} else {
NSUInteger childViewControllerCount = currentViewController.childViewControllers.count;
if (childViewControllerCount > 0) {
currentViewController = currentViewController.childViewControllers.lastObject;
return currentViewController;
} else {
return currentViewController;
}
}
}
return currentViewController;
}
+ (UIViewController *)jsd_getRootViewController{
UIWindow* window = [[[UIApplication sharedApplication] delegate] window];
NSAssert(window, @"The window is empty");
return window.rootViewController;
}
是否允许左滑返回
if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
//YES;
}
全屏测滑返回
http://www.jianshu.com/p/bc85a3d37519
@interface LPNavigationController : UINavigationController
@property(nullable, nonatomic, readonly) UIGestureRecognizer *fullInteractivePopGestureRecognizer;
@end
@interface LPNavigationController ()
@property(nullable, nonatomic, readwrite) UIGestureRecognizer *fullInteractivePopGestureRecognizer;
@end
@implementation LPNavigationController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.interactivePopGestureRecognizer.enabled = NO;
UIView *view = self.interactivePopGestureRecognizer.view;
id target = self.interactivePopGestureRecognizer.delegate;
SEL action = NSSelectorFromString(@"handleNavigationTransition:");
self.fullInteractivePopGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:target action:action];
self.fullInteractivePopGestureRecognizer.delaysTouchesBegan = YES;
self.fullInteractivePopGestureRecognizer.delegate = self;
[view addGestureRecognizer:self.fullInteractivePopGestureRecognizer];
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
// 左滑时可能与UITableView左滑删除手势产生冲突
CGPoint translation = [(UIPanGestureRecognizer *)gestureRecognizer translationInView:gestureRecognizer.view];
if (translation.x <= 0)
{
return NO;
}
// 跟视图控制器不响应手势
return ([self.viewControllers count] == 1) ? NO : YES;
}
@end
导航栏渐变
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
if (scrollView.contentOffset.y < 0) {
[self showView:self.navigationController.navigationBar hidden:YES];
}else if(scrollView.contentOffset.y > 50) {
[self showView:self.navigationController.navigationBar hidden:NO];
NSInteger barH = kScreenIphoneX?88:64;
CGFloat alpha = MIN(1, 1 - ((50 + barH - scrollView.contentOffset.y) / barH));
[self.navigationController.navigationBar setBackgroundColor:[mainThemeRed colorWithAlphaComponent:alpha]];
}else{
[self showView:self.navigationController.navigationBar hidden:NO];
[self.navigationController.navigationBar setBackgroundColor:[mainThemeRed colorWithAlphaComponent:0.0f]];
}
}
-(void)showView:(UIView *)view hidden:(BOOL)hidden{
CATransition *animation = [CATransition animation];
animation.type = kCATransitionFade;
animation.duration = 0.4;
[view.layer addAnimation:animation forKey:nil];
view.hidden = hidden;
}
导航栏颜色
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageWithColor:[UIColor greenColor] size:CGSizeMake(1, 1)] forBarMetrics:UIBarMetricsDefault];
背景图
[self.navigationBar setBackgroundImage:[UIImage imageNamed:@"navbar"] forBarMetrics:UIBarMetricsDefault];
获取前一个控制器 *
- (UIViewController *)backViewController
{
NSInteger myIndex = [self.navigationController.viewControllers indexOfObject:self];
if ( myIndex != 0 && myIndex != NSNotFound ) {
return [self.navigationController.viewControllers objectAtIndex:myIndex-1];
} else {
return nil;
}
}
获取View所在的控制器
- (UIViewController *)viewController
{
UIViewController *viewController = nil;
UIResponder *next = self.nextResponder;
while (next)
{
if ([next isKindOfClass:[UIViewController class]])
{
viewController = (UIViewController *)next;
break;
}
next = next.nextResponder;
}
return viewController;
}
状态栏颜色 设置
- (void)setStatusBarBackgroundColor:(UIColor *)color
{
UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
if ([statusBar respondsToSelector:@selector(setBackgroundColor:)])
{
statusBar.backgroundColor = color;
}
}
自定义navBar左按钮距左边的距离
UIBarButtonItem *leftItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"gobackItem.png"] style:UIBarButtonItemStylePlain target:self action:@selector(backViewcontroller)];
UIBarButtonItem *fixedItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
fixedItem.width = -16; // 设置边框距离,可根据需要调节
self.navigationItem.leftBarButtonItems = @[fixedItem, leftItem];
Navbar纯透明
//第一种方法
[self.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
//第二种方法
[[self.navigationBar subviews] objectAtIndex:0].alpha = 0;
去掉导航栏底部的黑线
self.navigationBar.shadowImage = [UIImage new];
根据滑动距离实现NavBar透明度渐变-隐藏-显示
- 第一种
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
//1、随滑动contentOffset控制透明度
CGFloat offsetToShow = 200.0;
CGFloat alpha = (offsetToShow - scrollView.contentOffset.y) / offsetToShow;
[[self.navigationController.navigationBar subviews] objectAtIndex:0].alpha = alpha;
//2、先隐藏,滑动多少就完全显示
CGFloat offsetToShow = 200.0;
CGFloat alpha = 1 - (offsetToShow - scrollView.contentOffset.y) / offsetToShow;
[[self.navigationController.navigationBar subviews] objectAtIndex:0].alpha = alpha;
}
- 第二种
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat offsetToShow = 200.0;
CGFloat alpha = 1 - (offsetToShow - scrollView.contentOffset.y) / offsetToShow;
[self.navigationController.navigationBar setShadowImage:[UIImage new]];
[self.navigationController.navigationBar setBackgroundImage:[self imageWithColor:[[UIColor orangeColor]colorWithAlphaComponent:alpha]] forBarMetrics:UIBarMetricsDefault];
}
- 停止滚动时显示导航栏
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
[[self.navigationController.navigationBar subviews] objectAtIndex:0].alpha = 1;
}
根据上滑 、 下滑决定隐藏导航栏
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{
NSLog(@"======== %lf", velocity.y);
if(velocity.y > 0) {
[self.navigationController setNavigationBarHidden:YES animated:YES];
}else {
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
}
velocity.y这个量,在上滑和下滑时变化极小(小数),但因为方向不同,有正负之分,这就很好处理了。
切换控制器时添加自定义动画
ViewController *VC = [ [ViewController alloc] init];
//创建动画
CATransition *animation = [CATransition animation];
//设置运动轨迹的速度
animation.timingFunction = UIViewAnimationCurveEaseInOut;
//设置动画类型为立方体动画
animation.type = @"cube";
//设置动画时长
animation.duration =1.0f;
//设置运动的方向
animation.subtype =kCATransitionFromRight;
//控制器间跳转动画
[[UIApplication sharedApplication].keyWindow.layer addAnimation:animation forKey:nil];
[self presentViewController:VC animated:NO completion:nil];
/*附:动画类型*/
typedef enum : NSUInteger {
fade = 1, //淡入淡出
push, //推挤
reveal, //揭开
moveIn, //覆盖
cube, //立方体
suckEffect, //吮吸
oglFlip, //翻转
rippleEffect, //波纹
pageCurl, //翻页
pageUnCurl, //反翻页
cameraIrisHollowOpen, //开镜头
cameraIrisHollowClose, //关镜头
curlDown, //下翻页
curlUp, //上翻页
flipFromLeft, //左翻转
flipFromRight, //右翻转
} AnimationType;
导航栏的隐藏与显示
有的页面需要导航栏,有的页面不想要导航栏。
采用self.navigationController.navigationBar.hidden = YES/NO;
进行设置,无法达到理想需求。
正确做法如下:
- 第一种做法
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
- 第二种做法 ( 推荐 )
@interface WLHomePageController ()
@end
@implementation WLHomePageController
#pragma mark - lifeCycle
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationController.delegate = self;
}
#pragma mark - 导航控制器 代理方法: 将要显示控制器
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
// 判断要显示的控制器是否是自己
BOOL isShowHomePage = [viewController isKindOfClass:[self class]];
[self.navigationController setNavigationBarHidden:isShowHomePage animated:YES];
}
统一设置导航items数据主题
+(void)setupNavigationItemsTheme {
UIBarButtonItem *barButtonItem = [UIBarButtonItem appearance];
// 设置字体颜色
[barButtonItem setTitleTextAttributes:@{
NSForegroundColorAttributeName : [UIColor blackColor],
NSFontAttributeName : [UIFont systemFontOfSize:14]}
forState:UIControlStateNormal];
[barButtonItem setTitleTextAttributes:@{
NSForegroundColorAttributeName : [UIColor redColor]}
forState:UIControlStateHighlighted];
[barButtonItem setTitleTextAttributes:@{
NSForegroundColorAttributeName : [UIColor lightGrayColor]}
forState:UIControlStateDisabled];
}
导航栏多个item
UIButton *addBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[addBtn addTarget:self action:@selector(clickRightItem:) forControlEvents:UIControlEventTouchUpInside];
[addBtn setImage:[UIImage imageNamed:@"note"] forState:UIControlStateNormal];
addBtn.tag = 1;
UIBarButtonItem *addBtnItem = [[UIBarButtonItem alloc] initWithCustomView:addBtn];
UIButton *scanBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[scanBtn addTarget:self action:@selector(clickRightItem:) forControlEvents:UIControlEventTouchUpInside];
[scanBtn setImage:[UIImage imageNamed:@"scan"] forState:UIControlStateNormal];
scanBtn.tag = 2;
UIBarButtonItem *scanBtnItem = [[UIBarButtonItem alloc] initWithCustomView:scanBtn];
UIBarButtonItem *space = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
space.width = 20;
self.navigationItem.rightBarButtonItems = @[addBtnItem,space,scanBtnItem];