-
前言:
-
开发中,搭建项目的基本框架,都会使用TabbarContrller外加嵌套导航控制器去搭建,为了能够快速搭建,节省开发时间,于是我会尽量偷懒,一些简单的代码能尽量能不写代码就尽量不写
TabBar控制器
// LYMMainTabBarVC.m
// 01 - MG的基本框架
// Created by ming on 14/12/1.
// Copyright © 2014年 ming. All rights reserved.
// 说明:
/**
* 参考代码:具体类和图片换一下即可用
*/
#import "LYMMainTabBarVC.h"
#import "LYMNavigationVC.h"
#import "LYMEssenceViewController.h"
#import "LYMNewViewController.h"
#import "LYMFriendViewController.h"
#import "LYMMeViewController.h"
#import "LYMTabBar.h"
@interface LYMMainTabBarVC ()<LYMTabBarDelaegate>
@end
@implementation LYMMainTabBarVC
- (void)viewDidLoad {
[super viewDidLoad];
// 1.当系统的Tabbar满足不了需求的时候,用自己的TabBar代替系统的TabBar
// [self setValue:[[LYMTabBar alloc] init] forKey:@"tabBar"];
// 2.初始化所有的自控制器
[self setUpAllChildController];
}
#pragma mark ========= initialize ===========
+ (void)initialize{
[[UITabBar appearance] setBackgroundImage:[UIImage imageNamed:@"tabbar-light"]];
NSDictionary *dict = @{
NSForegroundColorAttributeName:[UIColor grayColor]
};
[[UITabBarItem appearance] setTitleTextAttributes:dict forState:UIControlStateNormal];
}
#pragma mark ========= 初始化所有的子控制器 =========
/**
* 初始化所有的子控制器
*/
- (void)setUpAllChildController{
// 1.精华界面
LYMEssenceViewController *essenceCV = [[LYMEssenceViewController alloc] init];
[self setNavOneChildViewController:essenceCV title:@"精华" image:@"tabBar_essence_icon" selImage:@"tabBar_essence_click_icon"];
// 2.新手大厅
LYMNewViewController *newVC = [[LYMNewViewController alloc] init];
newVC.view.backgroundColor = [UIColor redColor];
[self setNavOneChildViewController:newVC title:@"新帖" image:@"tabBar_new_icon"
selImage:@"tabBar_new_click_icon"];
// 3.朋友
LYMFriendViewController *friendVC = [[LYMFriendViewController alloc] init];
[self setNavOneChildViewController:friendVC title:@"关注" image:@"tabBar_friendTrends_icon" selImage:@"tabBar_friendTrends_click_icon"];
// 4.我
LYMMeViewController *meVC = [[LYMMeViewController alloc] init];
meVC.view.backgroundColor = [UIColor purpleColor];
[self setNavOneChildViewController:meVC title:@"我" image:@"tabBar_me_icon"
selImage:@"tabBar_me_click_icon"];
}
/**
* 初始化一个子控制器的方法
*/
- (void)setNavOneChildViewController:(UIViewController *)vc title:(NSString *)title image:(NSString *)image selImage:(NSString *)selImage {
vc.tabBarItem.title = title;
vc.tabBarItem.image = [UIImage imageNamed:image];
vc.tabBarItem.selectedImage = [UIImage imageNamed:selImage];
[self addChildViewController:[[LYMNavigationVC alloc] initWithRootViewController:vc]];
}
@end
导航控制器
-
主要是重写push方法和设置全局导航栏样式,以及设置全局滑动返回手势
// BSNavigationController.m
// MGNaV
// Created by ming on 14/12/17.
// Copyright © 2014年 ming. All rights reserved.
#import "BSNavigationController.h"
#define BSBarButtonItemFont [UIFont systemFontOfSize:15]
@interface BSNavigationController ()<UIGestureRecognizerDelegate>
@end
@implementation BSNavigationController
/**
* 为什么在这里设置???
* 设置导航栏全局样式
* 因为这个只需要设置一次,因为这个方法程序只会执行一次
*/
+ (void)load{
/// 1.UINavigationBar
UINavigationBar *navBarAppearence = [UINavigationBar appearance];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
dict[NSFontAttributeName] = [UIFont systemFontOfSize:17];
[navBarAppearence setBackgroundImage:[UIImage imageNamed:@"navigationbarBackgroundWhite"] forBarMetrics:UIBarMetricsDefault];
[navBarAppearence setTitleTextAttributes:dict];
/// 2.UIBarButtonItem
UIBarButtonItem *barItemAppearence = [UIBarButtonItem appearance];
NSMutableDictionary *normalDict = [NSMutableDictionary dictionary];
normalDict[NSForegroundColorAttributeName] = [UIColor colorWithRed:0 green:0 blue:0 alpha:1];
normalDict[NSFontAttributeName] = BSBarButtonItemFont;
[barItemAppearence setTitleTextAttributes:normalDict forState:UIControlStateNormal];
NSMutableDictionary *highLDict = [NSMutableDictionary dictionary];
highLDict[NSForegroundColorAttributeName] = BSGlobalBgColor;
highLDict[NSFontAttributeName] = BSBarButtonItemFont;
[barItemAppearence setTitleTextAttributes:highLDict forState:UIControlStateHighlighted];
}
/*
<UIScreenEdgePanGestureRecognizer: 0x7fe260640220; view = <UILayoutContainerView 0x7fe26062bba0>;
target= <(action=handleNavigationTransition:,
target=<_UINavigationInteractiveTransition 0x7fe26063f1a0>)>>
1.UIScreenEdgePanGestureRecognizer 加在导航控制器的view上
2.target:_UINavigationInteractiveTransition(触发手势的对象)
3.action: handleNavigationTransition:(这个方法系统内部调用,不需要自己实现)
触发UIScreenEdgePanGestureRecognizer就会调用target的handleNavigationTransition:方法
*/
- (void)viewDidLoad {
[super viewDidLoad];
// UIScreenEdgePanGestureRecognizer
// Do any additional setup after loading the view.
// 只要触发这个Pan手势,就会调用self对象pan方法
// 1.创建全屏手势
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self.interactivePopGestureRecognizer.delegate action:@selector(handleNavigationTransition:)];
// 控制手势什么时候触发
pan.delegate = self;
// 全屏滑动返回
[self.view addGestureRecognizer:pan];
// 2.禁止边缘手势
self.interactivePopGestureRecognizer.enabled = NO;
// 实现滑动返回功能
// self.interactivePopGestureRecognizer.delegate = self;
// bug:假死:程序一直运行,但是界面动不了.
// 在根控制器的view,不需要滑动返回,
// 全屏滑动返回
// 研究下系统自带的返回手势
// NSLog(@"%@",self.interactivePopGestureRecognizer.delegate);
}
#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
// 不是根控制器就实现滑动返回功能
return self.childViewControllers.count != 1;
}
// 拦截控制器的push操作
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
// 判断是否为根控制器
if (self.childViewControllers.count > 0) { // 非根控制器
// 统一设置设置返回按钮
UIBarButtonItem *backItem = [UIBarButtonItem itemWithImage:[UIImage imageNamed:@"navigationButtonReturn"] highImage:[UIImage imageNamed:@"navigationButtonReturnClick"] norColor:BSColor(66, 66, 66) selColor:BSColor(255, 0, 0) title:@"返回" target:self action:@selector(backClick)];
viewController.navigationItem.leftBarButtonItem = backItem;
// 2.隐藏底部TabBar导航条
viewController.hidesBottomBarWhenPushed = YES;
}
[super pushViewController:viewController animated:animated];
}
// 出栈
- (void)backClick{
[self popViewControllerAnimated:YES];
}
@end
附注:当系统的Tabbar满足不了需求,很多时候,Tabbar界面上都会有个发布(➕)按钮,这时候就需要自定义Tabbar,而此文就是为快速解决这个问题而生
######################### .h文件 #########################
// BSTabBar.h
// MGTabBar
// Created by ming on 14/12/17.
// Copyright © 2014年 ming. All rights reserved.
#import <UIKit/UIKit.h>
@interface BSTabBar : UITabBar
/** 保存点击plusButton按钮之后要执行的代码 */
@property (nonatomic,strong) void(^operationBlock)();
@end
######################### .m文件 #########################
// BSTabBar.m
// MGTabBar
// Created by ming on 14/12/17.
// Copyright © 2014年 ming. All rights reserved.
#import "BSTabBar.h"
@interface BSTabBar ()
/** 发布按钮 */
@property (nonatomic,strong) UIButton *plusButton;
/** 记录上一次点击过的按钮的Tag */
@property (nonatomic,assign) NSInteger previousClicktag;
/** 记录上一次点击过的按钮 */
@property (nonatomic,strong) UIControl *previousClickTaBarButton;
@end
@implementation BSTabBar
/// 苹果也是懒加载的
// 懒加载plusButton并初始化该按钮
- (UIButton *)plusButton{
if (!_plusButton) {
_plusButton = [[UIButton alloc] init];
[_plusButton setImage:[UIImage imageNamed:@"tabBar_publish_icon"] forState:UIControlStateNormal];
[_plusButton setImage:[UIImage imageNamed:@"tabBar_publish_click_icon"] forState:UIControlStateHighlighted];
[_plusButton sizeToFit];
[self addSubview:_plusButton];
// 监听按钮的点击
[_plusButton addTarget:self action:@selector(plusButtonClick) forControlEvents:UIControlEventTouchUpInside];
}
return _plusButton;
}
// 重新布局TabBar的子控件
- (void)layoutSubviews{
[super layoutSubviews];
CGFloat width = self.width/( self.items.count + 1);
CGFloat height = self.height;
CGFloat x = 0;
CGFloat y = 0;
NSInteger i = 0;
for (UIControl *tabBarButton in self.subviews) {
if ([tabBarButton isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
if (i==2) {
i++;
}
x = i*width;
tabBarButton.frame = CGRectMake(x, y, width, height);
i++;
tabBarButton.tag = i;
[tabBarButton addTarget:self action:@selector(tabBarButtonClick:) forControlEvents:UIControlEventTouchUpInside];
/// 短时间内连续点击,类似于鼠标的双击事件
// [tabBarButton addTarget:self action:@selector(tabBarButtonClick:) forControlEvents:UIControlEventTouchDownRepeat];
}
}
// 计算plusButton的位置
self.plusButton.center = CGPointMake(self.width*0.5, self.height*0.5);
}
#pragma mark - 操作
// 监听加号➕按钮的点击
- (void)plusButtonClick{
if (self.operationBlock) {
self.operationBlock();
}
}
/**
* 重复点击TabBar的按钮,你想做什么事(比如:刷新界面)
*/
- (void)tabBarButtonClick:(UIControl *)tabBarButton{
if (self.previousClicktag == tabBarButton.tag) {
// 告诉其他人(按钮被重复点击了)
[[NSNotificationCenter defaultCenter] postNotificationName:BSTabBarButtonRepeatClickNotification object:nil];
}
self.previousClicktag = tabBarButton.tag;
}
@end