距离上一篇《第一个iOS应用》已经有一个多月了,今天来和大家一起学习和分享一下一个小练习《网易彩票》

首先我们向storyboard中拖入一个TabBarController和5个NavigationController,如下:

我们先来看看什么是导航控制器

1、导航控制器

“如果应用程序有多个内容视图层次,就需要能够在它们之间进行切换。为此,可以使用专门的视图控制器:导航控制器 (UINavigationController)。导航控制器管理在一系列视图控制器中向后和向前切换的操作,例如用户在 iOS 版“邮件”应用程序的电子邮件帐户、收件箱邮件和单封电子邮件之间导航。

我们将由特定导航控制器所管理的一组视图控制器称为其导航栈。导航栈是一组后进先出的自定视图控制器对象。添加到堆栈的第一个项目将变成根视图控制器,永不会从堆栈中弹出。而其他视图控制器可被压入或弹出导航栈。

虽然导航控制器的最主要作用是管理内容视图控制器的显示方式,但它还负责显示自己的自定视图。具体来说,它会显示导航栏(位于屏幕顶部的视图,提供有关用户在导航层次中位置的上下文)。导航栏包含一个返回按钮和其他可以自定的按钮。添加到导航栈的每个视图控制器都会显示这个导航栏。您需要配置导航栏。

一般而言,您不必执行任何操作来将视图控制器弹出导航栈;导航控制器提供的返回按钮会实现该操作。但您需要手动将视图控制器压入堆栈中。可使用串联图来操作。”

有如下几个类型过度

Push:Push 过渡将目的视图控制器添加到导航栈。只有当源视图控制器与导航控制器连接时,才可以使用 Push 过渡。

Modal:简单而言,Modal 过渡就是一个视图控制器以模态方式显示另一个控制器,需要用户在显示的控制器上执行某种操作,然后返回到应用程序的主流程。Modal 视图控制器不会添加到导航栈;相反,它通常被认为是所显示的视图控制器的子视图控制器。显示的视图控制器的作用是关闭它所创建和显示的 Modal 视图控制器。

Custom:可以通过将 UIStoryboardSegue 子类化来定义自定过渡。

Unwind:Unwind 过渡通过向后移动一个或多个过渡,让用户返回到视图控制器的当前实例。使用 Unwind 过渡可以实现反向导航。

除了过渡之外,还可以通过关系来连接场景。例如,导航控制器与其根视图控制器之间就存在关系。就此而言,这种关系表示导航控制器包含根视图控制器。

使用串联图规划应用程序的用户界面时,要确定将其中一个视图控制器标记为初始视图控制器,这一点尤为重要。运行时,该视图控制器的内容视图会在应用程序首次启动时显示,且在需要时,您可以从该视图控制器切换到其他视图控制器的内容视图。

上图表示一种包含关系

关于storyboard详细请看:https://developer.apple.com/library/ios/recipes/xcode_help-IB_storyboard/chapters/AboutStoryboards.html#//apple_ref/doc/uid/TP40014225-CH41-SW1

"A navigation controller object manages the currently displayed screens using the navigation stack, which is represented by an array of view controllers."

上面是官网对导航控制器的描述,大意是,一个导航控制器通过导航栈管理着一组视图控制器来控制当前显示的屏幕视图(英文很烂

二、自定义TabBar

新建CustomTabBar继承字UIView

#import <UIKit/UIKit.h>

@interface CustomTabBar : UIView

@end

要能访问到UITabBar就要重新写UITabBarController

#import "CustomTabBarController.h"
#import "CustomTabBar.h" @interface CustomTabBarController () @end @implementation CustomTabBarController - (void)viewDidLoad {
[super viewDidLoad];
//移除系统自带的tabBar
[self.tabBar removeFromSuperview]; //添加自己的tabBar
CustomTabBar *myTabBar = [[CustomTabBar alloc] init];
myTabBar.frame = self.tabBar.frame;
myTabBar.backgroundColor = [UIColor greenColor];
[self.view addSubview:myTabBar]; //添加5个按钮
for (int i = 0; i < 5; i++) {
//创建按钮
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
//设置图片
NSString *name = [NSString stringWithFormat:@"TabBar%d", i + 1];
[button setBackgroundImage:[UIImage imageNamed:name] forState:(UIControlStateNormal)];
//设置frame
CGFloat buttonY = 0;
CGFloat buttonW = myTabBar.frame.size.width * 0.2;
CGFloat buttonH = myTabBar.frame.size.height;
CGFloat buttonX = i * buttonW;
button.frame = CGRectMake(buttonX, buttonY, buttonW, buttonH);
//添加
[myTabBar addSubview:button];
}
} @end

三、实现标签导航效果

如上图所示,建立Relationship Segue

工程目录如下:

首先,自定义TabBarButton

#import "CustomTabBarButton.h"

@implementation CustomTabBarButton

- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if(self){ }
return self;
} //覆盖该方法,按钮就不存在高亮状态
- (void)setHighlighted:(BOOL)highlighted{ } @end

自定义TabBar

#import <UIKit/UIKit.h>

@class CustomTabBar;

@protocol MyTabBarDelegate <NSObject>

@optional
- (void)tabBar:(CustomTabBar *)tabBar didSelectButtonFrom:(int)from to:(int)to; @end @interface CustomTabBar : UIView @property (nonatomic, weak) id<MyTabBarDelegate> delegate; /**
* 用来添加一个内部的按钮
*
* @param name 按钮图片
* @param selName 按钮选中时的图片
*/
- (void)addTabButtonWithName:(NSString *)name selName:(NSString *)selName; @end
#import "CustomTabBar.h"
#import "CustomTabBarButton.h" @interface CustomTabBar() //记录当前选中的按钮
@property (nonatomic, weak)CustomTabBarButton *selectedButton; @end @implementation CustomTabBar - (void)addTabButtonWithName:(NSString *)name selName:(NSString *)selName{
//创建按钮
CustomTabBarButton *button = [CustomTabBarButton buttonWithType:UIButtonTypeCustom];
//设置图片
[button setBackgroundImage:[UIImage imageNamed:name] forState:UIControlStateNormal];
[button setBackgroundImage:[UIImage imageNamed:selName] forState:UIControlStateSelected]; //添加按钮
[self addSubview:button]; //监听按钮按下
[button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchDown]; //默认选择第0个按钮
if(self.subviews.count == 1){
[self buttonClick:button];
}
} - (void) layoutSubviews{
[super layoutSubviews];
int count = self.subviews.count;
for(int i = 0; i < count; i++){
CustomTabBarButton *button = self.subviews[i];
button.tag = i; //设置frame
CGFloat buttonY = 0;
CGFloat buttonW = self.frame.size.width / count;
CGFloat buttonH = self.frame.size.height;
CGFloat buttonX = i * buttonW;
button.frame = CGRectMake(buttonX, buttonY, buttonW, buttonH);
}
} /**
* 监听按钮点击
*/
- (void)buttonClick:(CustomTabBarButton *)button{
//通知代理
if([self.delegate respondsToSelector:@selector(tabBar:didSelectButtonFrom:to:)]){
[self.delegate tabBar:self didSelectButtonFrom:self.selectedButton to:button.tag];
} //让当前选中的按钮取消选中
self.selectedButton.selected = NO;
//让新点击的按钮选中
button.selected = YES;
//新点击的按钮就成为了“当前选中的按钮”
self.selectedButton = button;
} @end

在上面我们定义了一个代理用来通知TabBar上面的选择事件(点击)事件。

最后在TabBarController中设置我们自定义的TabBar并处理选择的界面

#import "MyTabBarController.h"
#import "CustomTabBar.h"
#import "CustomTabBarButton.h" @interface MyTabBarController () <MyTabBarDelegate> @end @implementation MyTabBarController - (void)viewDidLoad {
[super viewDidLoad]; //1.添加自己的tabbar
CustomTabBar *customTabBar = [[CustomTabBar alloc] init];
customTabBar.delegate = self;
customTabBar.frame = self.tabBar.bounds;
[self.tabBar addSubview:customTabBar]; //2.添加对应个数的按钮
for(int i = 0; i < self.viewControllers.count; i++){
NSString *name = [NSString stringWithFormat:@"TabBar%d", i + 1];
NSString *selName = [NSString stringWithFormat:@"TabBar%dSel", i + 1];
[customTabBar addTabButtonWithName:name selName:selName];
} //3.设置导航栏外观
UINavigationBar *navBar = [UINavigationBar appearance];
[navBar setBackgroundImage:[UIImage imageNamed:@"NavBar64"] forBarMetrics:UIBarMetricsDefault];
} - (void)tabBar:(CustomTabBar *)tabBar didSelectButtonFrom:(int)from to:(int)to{
self.selectedIndex = to;
} @end

四、设置导航栏和状态栏

我们重写NavigationController来实现导航栏的自定义

/**
* 系统在第一次使用这个类的时候调用(1个类只会调用一次)
*/
+ (void)initialize
{
// 设置导航栏主题
UINavigationBar *navBar = [UINavigationBar appearance];
// 设置背景图片
NSString *bgName = nil;
if (iOS7) { // 至少是iOS 7.0
bgName = @"NavBar64";
} else { // 非iOS7
bgName = @"NavBar";
}
[navBar setBackgroundImage:[UIImage imageNamed:bgName] forBarMetrics:UIBarMetricsDefault]; // 设置标题文字颜色
NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
attrs[UITextAttributeTextColor] = [UIColor whiteColor];
attrs[UITextAttributeFont] = [UIFont systemFontOfSize:16];
[navBar setTitleTextAttributes:attrs];
} /**
* 重写这个方法,能拦截所有的push操作
*
*/
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
viewController.hidesBottomBarWhenPushed = YES;
[super pushViewController:viewController animated:animated];
}

上面判断了当前的sdk版本,如果是ios7以上则导航栏的高度应该是64,ios6则是44,使用两个不同的背景。

重写pushViewController方法实现对底部TabBar的隐藏做统一处理。

// 判断是否为iOS7
#define iOS7 ([[UIDevice currentDevice].systemVersion doubleValue] >= 7.0)

在AppDelegate中设置状态栏的颜色

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
// 设置状态栏的样式
application.statusBarStyle = UIStatusBarStyleLightContent;
return YES;
}

iOS菜鸟成长笔记(2)——网易彩票练习的更多相关文章

  1. iOS菜鸟成长笔记(3)——斯坦福公开课学习(1)

    一.iOS四层结构 1.Core OS 是用FreeBSD和Mach所改写的Darwin, 是开源.符合POSIX标准的一个Unix核心.这一层包含或者说是提供了整个iPhone OS的一些基础功能, ...

  2. iOS菜鸟成长笔记(1)——第一个iOS应用

    前言:阳光小强最近抽时间学习iOS开发,在学习过程中发现了很多有趣的东西也遇到了很多问题,为了在学习过程中能和大家交流,记录下学习的心得和学习成果,所以就有了这一个系列文章,希望这一系列文章能形成一个 ...

  3. AJ学IOS(44)之网易彩票自定义图片在右边的Button_弹出view_ios6,7简单适配

    AJ分享,必须精品 效果: 注意图里面了吗,其实那个效果做起来真的很简单,在iOS中苹果给我们封装的很好,关键是那个按钮 系统的按钮的图片是在左边的,这里我们需要把他调整到右边,然后呢需要我们自己做一 ...

  4. iOS项目开发之仿网易彩票推荐应用

    简介 效果展示 思路分析 代码实现 Git地址 一.简介 某些公司有较多的产品时,通常会在一个产品中推广另外的一些产品,我简单的封装了一个UIControllerView,由于不同公司,要求不同.所以 ...

  5. AJ学IOS(43)之网易彩票底部自定义TabBar实现切换

    AJ分享,必须精品 效果: 代码: NYTabBarController // // NYTabBarController.m // 彩票lottery // // Created by apple ...

  6. AJ学IOS(47)之网易彩票帮助界面UIWebView的运用

    AJ分享,必须精品 效果: 制作过程 首先是帮助按钮那个地方的点击. 这里是用点击跳转的用的是 NJSettingArrowItem,前面的设置的,从字典通过模型转过来的. // 分享 NJSetti ...

  7. AJ学IOS(46)之网易彩票幸运大转盘

    AJ分享,必须精品 效果 实现过程: 基础UI搭建 这里主要是用了xib搭建,首先我们分析,有中间的开始按钮,背景图片,还有星座按钮,这里能用xib做的事开始按钮和背景图片. 如图: 星座按钮的搭建: ...

  8. 菜鸟成长日记之新手备忘录-IOS开发第一个项目总结

    2013年5月3号,开始找IOS开发工作(自学了大半年,做了一个功能不全的Demo,该出去见见世面了!),5月4号面试了第一家公司(是家刚成立一段时间的外包公司),5月5号第一家公司已二轮电话面试,5 ...

  9. Android菜鸟的成长笔记(3)——给QQ登录界面说So Easy

    原文:Android菜鸟的成长笔记(3)--给QQ登录界面说So Easy 上一篇:Android菜鸟的成长笔记(2)--第一个Android应用 我们前面已经做了第一个Android应用程序,虽然有 ...

随机推荐

  1. offsetLeft,Left,clientLeft具体解释

      假设 obj 为某个 HTML 控件. obj.offsetTop 指 obj 相对于版面或由 offsetParent 属性指定的父坐标的计算上側位置,整型,单位像素. obj.offsetLe ...

  2. C 语言运算符优先级(记忆口诀)

    优先级 运算符 名称或含义 使用形式 结合方向 说明 1 [] 数组下标 数组名[常量表达式] 左到右   () 圆括号 (表达式)/函数名(形參表)   . 成员选择(对象) 对象.成员名   -& ...

  3. 安卓WebView的使用,在应用程序中嵌入一个浏览器,轻松地展示各种各样的网页

    WebView 在应用程序中嵌入一个浏览器,轻松地展示各种各样的网页. 1.定义一个WebView位置 <?xml version="1.0" encoding=" ...

  4. ios修改了coredata数据结构后,更新安装会闪退

    如果iOS App 使用到CoreData,并且在上一个版本上有数据库更新(新增表.字段等操作),那在覆盖安装程序时就要进行CoreData数据库的迁移,具体操作如下: 1.选中你的mydata.xc ...

  5. Objective-c 中如何重写父类的初始化方法

    在我们的日常开发中我们经常会定义一些自己的子类继承一些UIKit 库中的类,那我们应该如何重写的这些初化方法呢?那我们先看看这些类有哪些初初化方法吧.(这里就用UIView为例) - (id)init ...

  6. SSH Key的生成和使用(for git)

    SSH Key的生成和使用 一.总结 1.用git base生成ssh,会生成id_rsa.pub文件,还有一个私钥文件.     $ ssh-keygen -t rsa -C “youremailn ...

  7. mysql表空间传输(ERROR 1808) row_format设置

    文章结构如下: 从MYSQL5.6版本开始,引入了传输表空间这个功能,可以把一张表从一个数据库移到另一个数据库或者机器上.迁移的时候很方便,尤其是大表. 由于本次达到测试使用版本5.6.38传到5.7 ...

  8. mysql裸文件备份XtraBackup (innobackupex)

    结构如下: 热备分为逻辑备份和裸文件备份. 裸文件备份比逻辑备份在速度上更快一些,因为它在底层复制数据文件.世界上唯一一款开源的,能够对INNODB和XtrDB数据库进行热备的开源工具. 他的优点是备 ...

  9. svn创建分支的做法

    作者:朱金灿 来源:http://blog.csdn.net/clever101 1.  首先选择你要创建分支的工作目录,如下图: 2.选择要创建分支的路径.注释以及版本,选择HEADrevision ...

  10. js 40 个技巧

    1. oncontextmenu="window.event.returnValue=false" 将彻底屏蔽鼠标右键<table border oncontextmenu= ...