AJ学IOS 之微博项目实战(2)微博主框架-自定义导航控制器NavigationController
AJ分享,必须精品
一:添加导航控制器
上一篇博客完成了对底部的TabBar的设置,这一章我们完成自定义导航控制器(NYNavigationController)。
为啥要做自定义呢,因为为了更好地封装代码,并且系统的UINavigationController不能满足我们的需求了,所以得自定义。
首先,我们在NYTabBarViewController的
- (void)addChildVc:(UIViewController )childVc title:(NSString )title image:(NSString )image selectedImage:(NSString )selectedImage方法中写了这个:
// 先给外面传进来的小控制器 包装 一个导航控制器
NYNavigationController *nav = [[NYNavigationController alloc] initWithRootViewController:childVc];
// 添加为子控制器
[self addChildViewController:nav];
来给设置的各个Controller包装一个导航控制器。
这时候系统会自动给添加一个。然后呢我们要对导航控制器进行改进。
框架结构
目前情况下的UI架构如下图所示:一个IWTabBarController拥有4个导航控制器作为子控制器,每个导航控制器都有自己的根控制器(栈底控制器)
重要代码
1.给控制器包装一个导航控制器并且放入tabbarController中
// 先给外面传进来的小控制器 包装 一个导航控制器
NYNavigationController *nav = [[NYNavigationController alloc] initWithRootViewController:childVc];
// 添加为子控制器
[self addChildViewController:nav];
二:导航控制器左右item的设置
在NYMessageCenterViewController中我们添加了cell,并使之可以点击,点击后进入到另一个界面(test1) 再点击界面的view进入另外一个界面(test2)
首先放入20行假数据——UITableView的数据源方法
返回一组,20行,每行内容cell设置
#pragma mark - Table view data source 数据源方法
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
// Return the number of rows in the section.
return 20;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *ID = @"ID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
}
cell.textLabel.text = [NSString stringWithFormat:@"test~~~~message - %d", indexPath.row];
return cell;
}
然后是cell的点击方法了 不用死记全部方法名字,简单敲一下tableview 查找didSele方法(学iOS对英语挺高老快了)灵活运用xcode的自动提示功能。
#pragma mark - 代理方法
//cell的点击事件
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NYTest1ViewController *test1 = [[NYTest1ViewController alloc] init];
test1.title = @"测试1控制器";
[test1.navigationController setNavigationBarHidden:NO];
[self.navigationController pushViewController:test1 animated:YES];
}
test1是我们自己做的一个测试类,其中我们做了两个如图:
这时候,我们的消息界面就有了cell的数据并且可以点击了。如图效果:
(到test2的push和1的一样,不过是用的view的touch方法)
这时候我们要做导航控制器的左右item了。
然后我们设置导航控制器的左右item (写私信按钮等)
如图:
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"写私信" style:UIBarButtonItemStylePlain target:self action:@selector(composeMsg)];
//设置右侧按钮为不可点击状态
self.navigationItem.rightBarButtonItem.enabled = NO;
NYLog(@"NYMessageCenterViewController-viewDidLoad");
}
其中的UIBarButtonItem 的创建方法不是系统给的,而是我们为了实现黄色的效果自己写的分类实现的。
分类实现UIBarButtonItem的自定义创建方法:
//
// UIBarButtonItem+Extension.m
// 猫猫微博
//
// Created by apple on 15-6-4.
// Copyright (c) 2015年 znycat. All rights reserved.
//
#import "UIBarButtonItem+Extension.h"
@implementation UIBarButtonItem (Extension)
/**
* 创建一个item
*
* @param target 点击item后调用哪个对象的方法
* @param action 点击item后调用target的哪个方法
* @param image 图片
* @param highImage 高亮的图片
*
* @return 创建完的item
*/
+(UIBarButtonItem *)itemWithTarget:(id)target action:(SEL)action image:(NSString *)image highImage:(NSString *)highImage
{
UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
//设置图片
[backBtn setBackgroundImage:[UIImage imageNamed:image] forState:UIControlStateNormal];
[backBtn setBackgroundImage:[UIImage imageNamed:highImage] forState:UIControlStateHighlighted];
[backBtn addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
//设置尺寸
CGSize imageSize = backBtn.currentBackgroundImage.size;
backBtn.frame = CGRectMake(0, 0, imageSize.width, imageSize.height);
UIBarButtonItem *itemBtn = [[UIBarButtonItem alloc] initWithCustomView:backBtn];
return itemBtn;
}
@end
这里设置尺寸用到了
CGSize imageSize = backBtn.currentBackgroundImage.size;
在我们学习UI的transform的时候,我们知道 是不能直接这么设置size的,但是为啥这里能呢? 很简单 ,我们对UIView写了一个分类
//
// UIView+Extension.m
// 猫猫微博
//
// Created by apple on 15-6-2.
// Copyright (c) 2015年 znycat. All rights reserved.
//
#import "UIView+Extension.h"
@implementation UIView (Extension)
-(void)setX:(CGFloat)x
{
CGRect frame = self.frame;
frame.origin.x = x;
self.frame = frame;
}
-(CGFloat)x
{
return self.frame.origin.x;
}
-(void)setY:(CGFloat)y
{
CGRect frame = self.frame;
frame.origin.y = y;
self.frame = frame;
}
-(CGFloat)y
{
return self.frame.origin.y;
}
-(void)setWidth:(CGFloat)width
{
CGRect frame = self.frame;
frame.size.width = width;
self.frame = frame;
}
-(CGFloat)width
{
return self.frame.size.width;
}
-(void)setHeight:(CGFloat)height
{
CGRect frame = self.frame;
frame.size.height = height;
self.frame = frame;
}
-(CGFloat)height
{
return self.frame.size.height;
}
-(void)setSize:(CGSize)size
{
CGRect frame = self.frame;
frame.size = size;
self.frame = frame;
}
-(CGSize)size
{
return self.frame.size;
}
-(void)setOrigin:(CGPoint)origin
{
CGRect frame = self.frame;
frame.origin = origin;
self.frame = frame;
}
-(CGPoint)origin
{
return self.frame.origin;
}
@end
并且为了改变系统原生的 美丽的蓝色情调,换成微博的黄色。。。
我们要重写NYNavigationController初始加载方法 (initialize)以及重写pushViewController方法,让push 的时候会自动带着箭头按钮和右边的更多按钮(UIBarButtonItem)
//
// NYNavigationController.m
// 猫猫微博
//
// Created by apple on 15-6-4.
// Copyright (c) 2015年 znycat. All rights reserved.
//
#import "NYNavigationController.h"
@interface NYNavigationController ()
@end
@implementation NYNavigationController
+(void)initialize
{
// 设置整个项目所有item的主题样式
UIBarButtonItem *item = [UIBarButtonItem appearance];
// 普通状态
NSMutableDictionary *textAttrsNormal = [NSMutableDictionary dictionary];
textAttrsNormal[NSForegroundColorAttributeName] = [UIColor orangeColor];
textAttrsNormal[NSFontAttributeName] = [UIFont systemFontOfSize:14];
[item setTitleTextAttributes:textAttrsNormal forState:UIControlStateNormal];
// 不可用状态
NSMutableDictionary *textAttrsDisabled = [NSMutableDictionary dictionary];
textAttrsDisabled[NSFontAttributeName] = [UIFont systemFontOfSize:14];
textAttrsDisabled[NSForegroundColorAttributeName] = [UIColor colorWithRed:0.6 green:0.6 blue:0.6 alpha:0.7];
[item setTitleTextAttributes:textAttrsDisabled forState:UIControlStateDisabled];
}
/**
* 重写这个方法目的:能够拦截所有push进来的控制器
*
* @param viewController 即将push进来的控制器
*/
-(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
// 这时push进来的控制器viewController,不是第一个子控制器(不是根控制器)
if (self.viewControllers.count > 0) {
/* 自动显示和隐藏tabbar */
viewController.hidesBottomBarWhenPushed = YES;
// 设置左边的箭头按钮
viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem itemWithTarget:self action:@selector(back) image:@"navigationbar_back" highImage:@"navigationbar_back_highlighted"];
// 设置右边的更多按钮
viewController.navigationItem.rightBarButtonItem = [UIBarButtonItem itemWithTarget:self action:@selector(more) image:@"navigationbar_more" highImage:@"navigationbar_more_highlighted"];
}
[super pushViewController:viewController animated:animated];
}
-(void)back
{
#warning 这里要用self,不是self.navigationController
// 因为self本来就是一个导航控制器,self.navigationController这里是nil的
[self popViewControllerAnimated:YES];
}
-(void)more
{
//回到根
[self popToRootViewControllerAnimated:YES];
}
@end
最后就是各个页面的调用了
首页:
- (void)viewDidLoad
{
[super viewDidLoad];
/* 设置导航栏上面的内容 */
self.navigationItem.leftBarButtonItem = [UIBarButtonItem itemWithTarget:self action:@selector(friendSearch) image:@"navigationbar_friendsearch" highImage:@"navigationbar_friendsearch_highlighted"];
self.navigationItem.rightBarButtonItem = [UIBarButtonItem itemWithTarget:self action:@selector(pop) image:@"navigationbar_pop" highImage:@"navigationbar_pop_highlighted"];
}
我:
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"设置" style:0 target:self action:@selector(setting)];
}
消息里面的写私信(这里设置默认不可用状态)
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"写私信" style:UIBarButtonItemStylePlain target:self action:@selector(composeMsg)];
//设置右侧按钮为不可点击状态
self.navigationItem.rightBarButtonItem.enabled = NO;
NYLog(@"NYMessageCenterViewController-viewDidLoad");
}
AJ学IOS 之微博项目实战(2)微博主框架-自定义导航控制器NavigationController的更多相关文章
- AJ学IOS 之微博项目实战(1)微博主框架-子控制器的添加
AJ分享,必须精品 一:简单介绍 这是新浪微博的iOS端项目,来自于黑马的一个实战项目. 主要分成五大模块,本次全部运用纯代码实现,其中会用到很多前面学过得内容,如果有的地方有重复的知识点,说明这个知 ...
- 猫猫学iOS 之微博项目实战(2)微博主框架-自己定义导航控制器NavigationController
猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents 一:加入导航控制器 上一篇博 ...
- AJ学IOS 之微博项目实战(5)微博自定义搜索框searchBar
AJ分享,必须精品 一:效果 用UITextField简单定义一个搜索框 二:调用: 调用的代码,很简单,直接init就可以,以后加功能自己添加就行了. - (void)viewDidLoad { [ ...
- AJ学IOS 之微博项目实战(10)微博cell中图片的显示以及各种填充模式简介
AJ分享,必须精品 :一效果 如果直接设置会有拉伸等等的状况,这里主要介绍图片显示的一些细节 二:代码 代码实现其实很简单,微博当中用了一个photos来存放九宫格这些图片,然后用了一个photo类来 ...
- AJ学IOS 之微博项目实战(9)微博模型之时间相关重要操作,判断刚刚,昨天,今年等等
AJ分享,必须精品 一:效果 二:实现代码 /** 1.今年 1> 今天 * 1分内: 刚刚 * 1分~59分内:xx分钟前 * 大于60分钟:xx小时前 2> 昨天 * 昨天 xx:xx ...
- AJ学IOS 之微博项目实战(4)微博自定义tabBar中间的添加按钮
AJ分享,必须精品 一:效果图 自定义tabBar实现最下面中间的添加按钮 二:思路 首先在自己的tabBarController中把系统的tabBar设置成自己的tabBar(NYTabBar),这 ...
- AJ学IOS 之微博项目实战(3)微博主框架-UIImage防止iOS7之后自动渲染_定义分类
AJ分享,必须精品 一:效果对比 当我们设置tabBarController的tabBarItem.image的时候,默认情况下会出现图片变成蓝色的效果,这是因为ios7之后会对图片自动渲染成蓝色 代 ...
- 猫猫学iOS 之微博项目实战(5)微博自己定义搜索框searchBar
猫猫分享.必须精品 原创文章.欢迎转载. 转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243 一:效果 用UITextField简单定义一个搜索框 二:调用 ...
- iOS彩票项目--第一天,自定义TabBar控制器和自定义TabBar,自定义导航控制器
一.环境配置,和项目层次搭建 二.自定义TabBar 项目中TabBar中的导航按钮美工给的图片太大,图片中包含了图片和文字.最主要的是TabBar上面的按钮图片尺寸是有规定的,当高度大于44的时候, ...
随机推荐
- scrapy框架Request函数callback参数为什么是self.parse而不是self.parse( )
加括号是调用函数,不加括号是指的是函数地址,此处只需要传入函数的地址,等待程序到时调用即可
- Django路由层与视图层、pycharm虚拟环境
一. Django路由层 路由层即对应项目文件下的urls.py文件.实际上每个APP中也可以有自己的urls.py路由层.templates文件夹及static文件夹.Django支持这么做,也为实 ...
- P2341 [USACO03FALL][HAOI2006]受欢迎的牛 G 题解
原题链接 POJ的链接 简要题意: 给定一张图,求多少个点,每个点都能到达它. 本题作为强连通分量的入门题. 何为强连通分量?有什么用? 下面一一解释. 首先,我们要确认,这道题目如果不用强连通分量而 ...
- Leetcode——回溯法常考算法整理
Leetcode--回溯法常考算法整理 Preface Leetcode--回溯法常考算法整理 Definition Why & When to Use Backtrakcing How to ...
- coding++:Java读写到览器Cookies中
首先我们认识下什么是cookies: cookie实际上是一个存在你硬盘里的数据,但是这些数据很特殊,只能由web应用提交给浏览器帮助存储,并且我们还能读取浏览器存在本地的cookie web应用一般 ...
- Python python 五种数据类型--元组
# 定义一个元组 var1 = ('Hello','Python') var2 = tuple() print(type(var1)) #<class 'tuple'> print(typ ...
- Windows 7 NVMe补丁(包括官网下载链接)
随着NVMe固态硬盘的普遍,很多想使用Windows 7,又想使用NVMe固态硬盘的,不得不打两个NVMe补丁 这两个补丁主要是:KB2990941和KB3087873 32位 百度网盘 64位 百度 ...
- JavaScript五子棋第二版
这是博主做的一个移动端五子棋小游戏,请使用手机体验.由于希望能有迭代开发的感觉,所以暂时只支持双人对战且无其他提示及对战界面,只有胜利提示,悔棋.对战双方显示.人机对战.集成TS(用于学习).和局 ...
- .net core 集成 sentry 进行异常报警
.net core 集成 sentry 进行异常报警 Intro Sentry 是一个实时事件日志记录和汇集的平台.其专注于错误监控以及提取一切事后处理所需信息而不依赖于麻烦的用户反馈.它分为客户端和 ...
- Java 中为什么不能创建泛型数组?
之前只是知道在 Java 中不能创建泛型数组,今天翻看 <Effective Java>其中对这个部分有讲解,记录一下. 现在我们假设在 Java 中可以创建泛型数组,看看可能会发生什么情 ...