iOS菜鸟成长笔记(2)——网易彩票练习(1)

距离上一篇《第一个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;
}
时间: 2024-12-04 22:12:01

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

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

一.iOS四层结构 1.Core OS 是用FreeBSD和Mach所改写的Darwin, 是开源.符合POSIX标准的一个Unix核心.这一层包含或者说是提供了整个iPhone OS的一些基础功能,比如:硬件驱动, 内存管理,程序管理,线程管理(POSIX),文件系统,网络(BSD Socket),以及标准输入输出等等,所有这些功能都会通过C语言的API来提供.另外,值得一题的是,这一层最具有UNIX色彩,如果你需要把 UNIX上所开发的程序移植到iPhone上,多半都会使用到Core OS的

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

前言:阳光小强最近抽时间学习iOS开发,在学习过程中发现了很多有趣的东西也遇到了很多问题,为了在学习过程中能和大家交流,记录下学习的心得和学习成果,所以就有了这一个系列文章,希望这一系列文章能形成一个系统性的东西,让和我一样刚步入iOS开发的朋友少走弯路,用最少的时间获得最大的收益.既然是学习笔记,希望大家多提意见,如果你是iOS大牛多多拍砖. 说起iOS开发很多朋友就会望而却步,有一部分朋友可能是因为设备因素,有一部分朋友可能是因为编程语言是Objective-C的原因,因为这些迟迟没有拿起的

iOS UI进阶-1.3网易彩票设置模块

概述 基本上,每一款APP都有相应的设置模块.怎么设置才能更灵活和通用呢,这也是大家一直思考的.下面说说在网易彩票中,设置模块的设置思想. 基本上有三种方案: static cell(呆板,完全没有动态) 使用代码,条件判断逐个编写(麻烦,代码冗长) 使用plist加载(能够动态配置跳转控制器,不能配置请求代码:由于使用字符串配置跳转控制器名,容易出现运行时错误) 使用模型封装每个cell的数据(item),使用Class作为跳转控制器属性(这样就能经过编译检测) 最终我们使用的是第4种方式来实

iOS UI进阶-1.0网易彩票框架搭建

仿网易彩票,最终要做成的效果如下: 一.分层搭建 1.新建一个项目,Lottery.只支持7.1以上坚屏. 2.将素材全部图片全部拉到相应的文件夹里. 3.选中Lottery--右键Show in Finder ,在Lottery文件夹下新建一个Classes,并分别分层成MVC文件夹. 4.把Classes拉到Lottery项目里,整个框架结构如 二.UI搭建 分层好之后,接下来,我们搭建一下界面.使用Storyboard进行搭建. 1.点击Main.storyboard,删除原来的界面,分别

iOS UI进阶-1.4网易彩票设置模块二

产品推荐 产品推荐使用的是UICollectionView控件,UICollectionView 和 UICollectionViewController 类是iOS6 新引进的API,用于展示集合视图,布局更加灵活,可实现多列布局,用法类似于UITableView 和 UITableViewController 类. 思路: 模型:建立一个MJProduct模型,存放产品的相关信息(标题.图标) 视图:创建xib,继承于UICollectionViewCell 控制器:创建MJProductV

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

简介 效果展示 思路分析 代码实现 Git地址 一.简介 某些公司有较多的产品时,通常会在一个产品中推广另外的一些产品,我简单的封装了一个UIControllerView,由于不同公司,要求不同.所以大家可以根据自己不同的需求来改里面的内容,希望对大家有用. 我这里解压网易的资源文件,获取到的数据.(如有任何问题,联系本人[email protected]) 二.效果展示 因为我的截图都是使用的模拟器,所以后面都显示的下载图标.如果用真机会根据用户是否下载了对应的应用来判断显示什么样的图片,以及

iOS UI进阶-1.2网易彩票常见设置

Navigation导航设置 为了统一管理导航控制器,需要自定义导航控制器MJNavigationController,继承于UINavigationController.分别设置5个Navigation的控制器Class为此控制器. 白色状态栏 统一背景头部导航栏 设置所有Navigation导航栏字体颜色 二级页面隐藏底部导航条 1.白色状态栏.使用application管理状态栏 设置不使用控制器控制状态栏 在MJAppDelegate中设置: - (BOOL)application:(U

iOS UI进阶-1.1网易彩票框架搭建-代码重构

在上一篇中,我们基本已经把整个框架都搭建出来了,下面进行代码重构一下. 思路: 导航按钮,按下时,会变灰,那是系统自带了,通过自定义UIButton,实现按下按钮立即切换效果. MJTabBarController管得太多了,只需要传图片过去,即创建好一个TabBar. 通过代理实现底部tabbar的切换. 一.自定义UIButton,继承自UIButton.MJTabBarButton.m #import "MJTabBarButton.h" @implementation MJTa

Android菜鸟的成长笔记(28)——Google官方对Andoird 2.x提供的ActionBar支持

在Google官方Android设计指南中(链接:http://www.apkbus.com/design/get-started/ui-overview.html)有一个新特性就是自我标识,也就是宣传自己,所以很多应用现在也自然的使用ActionBar并提供自己的logo. 微信的应用: Google的Android设计指南中是这样说的:应用的 启动图标 作为启动应用的入口是展示 logo 的最佳场所.你也可以将启动图标放置在 操作栏 上,从而保证在应用内的所有页面上都能看到它. 在使用Act