ios 自定导航栏 返回按钮

 导航控制器 默认 返回键盘默认是  一个箭头 + 上一个控制器名称,系统默认,以下图ios


  如何自定义左上角控制器返回按钮:数组

  解决方法: 
A控制器进入detail控制器app

- (IBAction)showDatail:(id)sender {
    // 注意: 控制器背景色不要在这里设置
    AControllerViewController* aController=[[AControllerViewController alloc] init];
    aController.hidesBottomBarWhenPushed=YES;
    [self.navigationController pushViewController:aController animated:YES];
    
}

Detail控制器:dom

#import "AControllerViewController.h"

@interface AControllerViewController ()

@end

@implementation AControllerViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.navigationItem.title=@"详情控制器";
    
    // 左上角
      UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
      [backButton setImage:[UIImage imageNamed:@"navigationButtonReturn"] forState:UIControlStateNormal];
      [backButton setImage:[UIImage imageNamed:@"navigationButtonReturnClick"] forState:UIControlStateHighlighted];
      [backButton setTitle:@"返回" forState:UIControlStateNormal];
      [backButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
      [backButton setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
      [backButton sizeToFit];
      // 这句代码放在sizeToFit后面
      backButton.contentEdgeInsets = UIEdgeInsetsMake(0, -20, 0, 0);
      [backButton addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
      self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
}


- (void)back
{
    [self.navigationController popViewControllerAnimated:YES];
}


@end

 效果图: ide

  

问题:  须要在每个控制器中写上面代码,一个项目有不少控制器
  解决方法1: 
  使用继承,BaseViewController 继承 UIViewController, 可是若是是UITableViewController
  没法使用, 要写 2个 继承的 子类 BaseTableViewController
  解决2:
  自定义导航控制器,重写 pushViewController方法 工具

自定义的时候注意点: spa

1. 自定义 leftBarButtonItem 之后, 默认右滑关闭控制器页面功能无效
 解决: 把手势加上便可3d

2. 不要在控制外面设置 控制器背景颜色, 
好比在 XMGTabBarController 设置  tab控制器颜色,A,B,C,B 到时控制器 都初始化,而不是显示的时候才初始化对应控制器代理

3. 若是A到 B控制器,B控制器 导航栏透明,那么能够看到A控制器透过 B 控制器,那么设置 导航栏 背景图片 便可
 XMGNavigationController 自定义 NavigationControllercode

#import "XMGNavigationController.h"

@interface XMGNavigationController () <UIGestureRecognizerDelegate>

@end

@implementation XMGNavigationController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    // 1. 自定义 leftBarButtonItem 之后, 默认右滑关闭控制器页面功能无效 解决 把手势加上便可
    self.interactivePopGestureRecognizer.delegate = self;
    // 3. 若是A到 B控制器,B控制器 导航栏透明,那么能够看到A控制器透过 B 控制器,那么设置 导航栏 背景图片 便可
    [self.navigationBar setBackgroundImage:[UIImage imageNamed:@"navigationbarBackgroundWhite"] forBarMetrics:UIBarMetricsDefault];
}

/**
 *  重写push方法的目的 : 拦截全部push进来的子控制器
 *
 *  @param viewController 刚刚push进来的子控制器
 */
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    // 必须判断
    /*
     TwoController *twoVC= [[TwoController alloc]init];
        UINavigationController* twoVCN= [[XMGNavigationController alloc] initWithRootViewController:twoVC];
           twoVCN.tabBarItem.title=@"B控制器";
           [self addChildViewController:twoVCN];
     执行该代码的时候也会执行  pushViewController,导航控制器下的控制器不能带返回
     */
    if (self.childViewControllers.count > 0) { // 若是viewController不是最先push进来的子控制器
        // 左上角
        UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [backButton setImage:[UIImage imageNamed:@"navigationButtonReturn"] forState:UIControlStateNormal];
        [backButton setImage:[UIImage imageNamed:@"navigationButtonReturnClick"] forState:UIControlStateHighlighted];
        [backButton setTitle:@"返回" forState:UIControlStateNormal];
        [backButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [backButton setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
        [backButton sizeToFit];
        // 这句代码放在sizeToFit后面
        backButton.contentEdgeInsets = UIEdgeInsetsMake(0, -20, 0, 0);
        [backButton addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
        viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
        
        // 隐藏底部的工具条
        viewController.hidesBottomBarWhenPushed = YES;
    }
    
    // 全部设置搞定后, 再push控制器
    [super pushViewController:viewController animated:animated];
}

//- (UIViewController *)popViewControllerAnimated:(BOOL)animated
//{
//    return [super popViewControllerAnimated:NO];
//}
//
//- (NSArray<UIViewController *> *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated
//{
//    return [super popToViewController:viewController animated:NO];
//}
//
//- (NSArray<UIViewController *> *)popToRootViewControllerAnimated:(BOOL)animated
//{
//    return [super popToRootViewControllerAnimated:NO];
//}

- (void)back
{
    [self popViewControllerAnimated:YES];
}

#pragma mark - <UIGestureRecognizerDelegate>
/**
 *  手势识别器对象会调用这个代理方法来决定手势是否有效
 *
 *  @return YES : 手势有效, NO : 手势无效
 */
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
//    if (self.childViewControllers.count == 1) { // 导航控制器中只有1个子控制器
//        return NO;
//    }
//    return YES;
    
    // 手势什么时候有效 : 当导航控制器的子控制器个数 > 1就有效
    return self.childViewControllers.count > 1;
}
@end

XMGTabBarController 设置: 

#import "XMGTabBarController.h"
#import "OneController.h"
#import "TwoController.h"
#import "ThreeController.h"
#import "FourController.h"
#import "ModelController.h"
#import "XMGTabBar.h"
#import "XMGNavigationController.h"


@interface XMGTabBarController ()

@end

@implementation XMGTabBarController

- (void)viewDidLoad {
    [super viewDidLoad];
    
   // 第一个子控制器
      OneController *oneVC= [[OneController alloc]init];
      UINavigationController* oneVCN= [[UINavigationController alloc] initWithRootViewController:oneVC];
      oneVCN.tabBarItem.title=@"A控制器";
      
      //1. 分别设置
      UIImage* image1= [UIImage imageNamed:@"navigationbar_friendsearch"];
      UIImage* selelctImage1= [UIImage imageNamed:@"navigationbar_friendsearch_highlighted"];
      // 系统会被默认图片渲染绿色,这里改变系统渲染图片的模式
      selelctImage1= [selelctImage1
                      imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
      oneVCN.tabBarItem.image = image1;
      oneVCN.tabBarItem.selectedImage = selelctImage1;

      // tabbarItem 设置文字 属性
      // 属性到  using the keys found in NSAttributedString.h 中找  UIKit下
      //
      [oneVCN.tabBarItem setBadgeValue:@"100"];
      NSMutableDictionary* normalAttrs= [NSMutableDictionary dictionary];
      normalAttrs[NSFontAttributeName]= [UIFont systemFontOfSize:14];
      normalAttrs[NSForegroundColorAttributeName]=[UIColor blackColor];
  //    [oneVC.tabBarItem setTitleTextAttributes:normalAttrs forState:UIControlStateNormal];
      
      
      NSMutableDictionary* selectAttrs= [NSMutableDictionary dictionary];
         selectAttrs[NSForegroundColorAttributeName]=[UIColor redColor];
         selectAttrs[NSFontAttributeName]= [UIFont systemFontOfSize:14];
  //    [oneVC.tabBarItem setTitleTextAttributes:selectAttrs forState:UIControlStateSelected];
      
      //2. 统一设置
      //setTitleTextAttributes:(nullable NSDictionary<NSAttributedStringKey,id> *)attributes forState:(UIControlState)state API_AVAILABLE(ios(5.0)) UI_APPEARANCE_SELECTOR;
      // 后面 有 UI_APPEARANCE_SELECTOR 能够经过 appear设置
      // 取出appear,统一设置,那么这个app中全部的 UITabBarItem 都有这个属性
      UITabBarItem* item= [UITabBarItem appearance];
      [item setTitleTextAttributes:normalAttrs forState:UIControlStateNormal];
      [item setTitleTextAttributes:selectAttrs forState:UIControlStateSelected];
     // [self addChildViewController:oneVC];
     [self addChildViewController:oneVCN];
      
      
      // 第二个子控制器
        TwoController *twoVC= [[TwoController alloc]init];
     UINavigationController* twoVCN= [[XMGNavigationController alloc] initWithRootViewController:twoVC];
        twoVCN.tabBarItem.title=@"B控制器";
        [self addChildViewController:twoVCN];
      
      // 中间 按钮,若是自定义   XMGTabBar 那么必须设置中间 控制器了
//      UIViewController* center =[[ UIViewController alloc] init];
//      [self addChildViewController: center];
    
      ThreeController *threeVC= [[ThreeController alloc]init];
       UINavigationController* threeVCN= [[XMGNavigationController alloc] initWithRootViewController:threeVC];
      threeVCN.tabBarItem.title=@"C控制器";
      [self addChildViewController:threeVCN];
      
    
      FourController *fourVC= [[FourController alloc]init];
      UINavigationController* fourVCN= [[XMGNavigationController alloc] initWithRootViewController:fourVC];
      fourVCN.tabBarItem.title=@"D控制器";
      [self addChildViewController:fourVCN];
    
    
  //    [tabBarVc addChildViewController:oneVC];
  //    [tabBarVc addChildViewController:twoVC];
  //    [tabBarVc addChildViewController:threeVC];
      
      //使用 数组的方式 同一设置
  //     tabBarVc.viewControllers=@[oneVC,twoVC,threeVC,fourVC];
    
    
    // 设置自定义tabbar
    // tabbar 是  readonly 不能直接设置,经过kvc 设置
   //  self.tabBar= [[XMGTabBar alloc] init];
    // kvc设置
    [self setValue:[[XMGTabBar alloc] init] forKeyPath:@"tabBar"];

    
}

- (void)viewWillAppear10:(BOOL)animated
{
    [super viewWillAppear:animated];
    
    /**** 增长一个发布按钮 ****/
// 这个方法会被调入屡次,好比,弹出模态窗口,串口消失的时候,会调用这个方法
    // 避免添加多个button
    //解决方法: 1.dispatch_once
    // 2.  懒加载  定义一个变量 publishButton
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{
        /**** 增长一个发布按钮 ****/
        UIButton *publishButton = [UIButton buttonWithType:UIButtonTypeCustom];
        publishButton.backgroundColor = XMGRandomColor;
        [publishButton setImage:[UIImage imageNamed:@"tabBar_publish_icon"] forState:UIControlStateNormal];
        [publishButton setImage:[UIImage imageNamed:@"tabBar_publish_click_icon"] forState:UIControlStateHighlighted];
        publishButton.frame = CGRectMake(0, 0, self.tabBar.frame.size.width / 5, self.tabBar.frame.size.height);
        publishButton.center = CGPointMake(self.tabBar.frame.size.width * 0.5, self.tabBar.frame.size.height * 0.5);
        [publishButton addTarget:self action:@selector(publishClick) forControlEvents:UIControlEventTouchUpInside];
        [self.tabBar addSubview:publishButton];
    });
}


-(void)publishClick{
    NSLog(@"helll");
    
     ModelController* modelVc= [[ModelController alloc] init];
     UINavigationController* nav= [[UINavigationController alloc] initWithRootViewController:modelVc];
    
     [self presentViewController:nav animated:YES completion:^{
         
     }];

}


@end