导航控制器 默认 返回键盘默认是 一个箭头 + 上一个控制器名称,系统默认,如下图
如何自定义左上角控制器返回按钮:
解决方法:
A控制器进入detail控制器
- (IBAction)showDatail:(id)sender {
// 注意: 控制器背景色不要在这里设置
AControllerViewController* aController=[[AControllerViewController alloc] init];
aController.hidesBottomBarWhenPushed=YES;
[self.navigationController pushViewController:aController animated:YES];
}
Detail控制器:
#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
效果图:
问题: 需要在每一个控制器中写上面代码,一个项目有很多控制器
解决方法1:
使用继承,BaseViewController 继承 UIViewController, 但是如果是UITableViewController
无法使用, 要写 2个 继承的 子类 BaseTableViewController
解决2:
自定义导航控制器,重写 pushViewController方法
自定义的时候注意点:
1. 自定义 leftBarButtonItem 以后, 默认右滑关闭控制器页面功能无效
解决: 把手势加上即可
2. 不要在控制外面设置 控制器背景颜色,
比如在 XMGTabBarController 设置 tab控制器颜色,A,B,C,B 到时控制器 都初始化,而不是显示的时候才初始化对应控制器
3. 如果A到 B控制器,B控制器 导航栏透明,那么可以看到A控制器透过 B 控制器,那么设置 导航栏 背景图片 即可
XMGNavigationController 自定义 NavigationController
#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