猫猫学iOS 之微博项目实战(2)微博主框架-自定义导航控制器NavigationController

猫猫分享,必须精品

原创文章,欢迎转载。转载请注明:翟乃玉的博客

地址:http://blog.csdn.net/u013357243?viewmode=contents

一:添加导航控制器

上一篇博客完成了对底部的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");

}
时间: 2024-08-04 18:24:38

猫猫学iOS 之微博项目实战(2)微博主框架-自定义导航控制器NavigationController的相关文章

猫猫学iOS 之微博项目实战(1)微博主框架-子控制器的添加

猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents 一:简单介绍 这是新浪微博的iOS端项目,来自于黑马的一个实战项目.(本人没有培训,纯属自学,但人要学会感恩,虽然是自己买的学习资料,但是饮水思源!!) 主要分成五大模块,本次全部运用纯代码实现,其中会用到很多前面学过得内容,如果有的地方有重复的知识点,说明这个知识点真的很重要,没有时间看视频学习或者培训的朋友们,可以看猫猫的

猫猫学iOS 之微博项目实战(2)微博主框架-自己定义导航控制器NavigationController

猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents 一:加入导航控制器 上一篇博客完毕了对底部的TabBar的设置,这一章我们完毕自己定义导航控制器(NYNavigationController). 为啥要做自己定义呢.由于为了更好地封装代码,而且系统的UINavigationController不能满足我们的需求了,所以得自己定义. 首先,我们在NYTabBarViewCon

猫猫学iOS 之微博项目实战(5)微博自己定义搜索框searchBar

猫猫分享.必须精品 原创文章.欢迎转载. 转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243 一:效果 用UITextField简单定义一个搜索框 二:调用: 调用的代码.非常easy,直接init就能够,以后加功能自己加入即可了. - (void)viewDidLoad { [super viewDidLoad]; // 创建搜索框 NYSearchBar *searchBar = [[NYSearchBar alloc] initWithFrame

猫猫学iOS 之微博项目实战(4)微博自定义tabBar中间的添加按钮

猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243 一:效果图 自定义tabBar实现最下面中间的添加按钮 二:思路 首先在自己的tabBarController中把系统的tabBar设置成自己的tabBar(NYTabBar),这里由于tabBar的属性是readonly的,所以我们要用kvc或者是消息管理来设置他 然后就写自己的NYTabBar.这个写起来首先 遍历当前tabBar上的所有view,如果是UI

猫猫学iOS 之微博项目实战(5)微博自定义搜索框searchBar

猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243 一:效果 用UITextField简单定义一个搜索框 二:调用: 调用的代码,很简单,直接init就可以,以后加功能自己添加就行了. - (void)viewDidLoad { [super viewDidLoad]; // 创建搜索框 NYSearchBar *searchBar = [[NYSearchBar alloc] initWithFrame:CGR

猫猫学iOS 之微博项目实战(10)微博cell中图片的显示以及各种填充模式简介

猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243 :一效果 如果直接设置会有拉伸等等的状况,这里主要介绍图片显示的一些细节 二:代码 代码实现其实很简单,微博当中用了一个photos来存放九宫格这些图片,然后用了一个photo类来做每个photo,并且在上面显示gif等的样式,很多很多小技巧,直接上代码 九宫格根据行列设置等算法,不难 #import "HWStatusPhotosView.h" #i

猫猫学iOS 之微博项目实战(9)微博模型之时间相关重要操作,判断刚刚,昨天,今年等等

猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243 一:效果 --因为本人黑苹果,系统时间乱跳 时间显示的不准,但是代码没有问题 二:实现代码 /** 1.今年 1> 今天 * 1分内: 刚刚 * 1分~59分内:xx分钟前 * 大于60分钟:xx小时前 2> 昨天 * 昨天 xx:xx 3> 其他 * xx-xx xx:xx 2.非今年 1> xxxx-xx-xx xx:xx */ - (NSSt

猫猫学iOS(四十四)之网易彩票自定义图片在右边的Button_弹出view_ios6,7简单适配

猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents 效果: 注意图里面了吗,其实那个效果做起来真的很简单,在iOS中苹果给我们封装的很好,关键是那个按钮 系统的按钮的图片是在左边的,这里我们需要把他调整到右边,然后呢需要我们自己做一下操作. 代码: 话不多说,先把所有代码放上来.能看懂就不用看别的了.(这么详细的注释,看不懂才怪..) 弹出view:NYBuyControlle

猫猫学iOS(四十三)之网易彩票底部自定义TabBar实现切换

猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents 效果: 代码: NYTabBarController // // NYTabBarController.m // 彩票lottery // // Created by apple on 15-5-9. // Copyright (c) 2015年 znycat. All rights reserved. // #import