您的位置:首页 > 移动开发 > IOS开发

九十六、利用 标签栏 创建 多视图iOS应用程序

2012-10-31 09:54 357 查看
到目前为止 我们创建的应用程序 只 向用户 展示 一个单一的视图。但是 在实际应用当中 我们 很有可能 需要根据用户所采取的不同行动 向用户 展示 不同的视图。在这种情况下 我们 需要创建 多个不同的视图,然后 利用 某种机制 允许 用户 在不同的视图之间 转换。这样的机制 有 用户界面导航栏(UINavigationBar)
和 用户界面标签栏(UITabBar)。


关于 标签栏(UITabBar)

典型的标签栏 位于 屏幕的底部。标签栏 会向用户 展现 一组标签,这些标签 一般 包含 文字 有时 也包含 图标。用户 只要点击 这些标签中的某一个 就会被带至 相应的视图。iphone内置的音乐 和 电话应用程序 就是 标签栏的典型应用。在iphone音乐应用程序当中 标签栏 提供了 播放列表、艺人、曲目、视频等标签。用户 点击 不同的标签,就会有 不同的视图 显示 给用户。


理解 多视图应用程序中的视图控制器

在之前的文章中 我们 谈论过 模型-视图-控制器的概念。每个视图 都有 自己的视图控制器 就与 这个概念 有关。在多视图应用程序当中 每个视图 同样 有 自己的视图控制器 用以处理 用户交互 和 内容更新。除此之外 多视图应用程序 还需要 一个额外的控制器。

多视图应用程序 需要 一个肉眼可见的物件,用户 用 它 来从一个视图 切换到 另外一个视图。这种肉眼可见的物件 一般 是 导航栏 或者 标签栏。无论 是 导航栏 还是 标签栏 都属于 视图,于是 他们 都需要 一个视图控制器,在多视图应用程序当中 这样的视图控制器 叫做 底层视图控制器。底层视图控制器 负责 控制 哪些视图 需要显示 在用户面前。作为开发者 我们 不必利用 UIViewController类型的物件 来创建 底层视图控制器,用
UITabBarController类型的物件 或者 UINavigationController类型的物件 来充当 底层视图控制器 则要更好一些。

无论 你 用 什么东西 来充当 底层视图控制器,它 都是 应用程序 启动后 第一个载入的控制器。一旦 底层视图控制器 载入后 它 就要负责 将 第一个视图 展现 给用户,然后 根据用户 与 应用程序的交互 在各个视图之间 切换。

既然 这篇博文 讲述 如何创建 基于标签栏的应用程序,那么 我们 就用 用户界面标签栏控制器(UITabBarController) 作为 我们的底层视图控制器。


创建 项目

创建应用程序的第一步 是 创建 一个Xcode项目。虽然 我们 可以在空模板的基础上 实现 标签栏的功能,但是 我们 也可以将 不少准备工作 留给 Xcode。先点击 基于标签栏的应用程序(Tabbed Application),然后 点击 下一步。

接着 我们 把 产品名称 和 物件类型名称前缀 设定为 TabBar。然后 将 设备家族(Device Family) 设定为 iphone 并且 将 使用故事板(Use Storyboard) 和 单元测试(Unit Test)两个选项 关掉。最后 将 这个项目 创建 在合适的地方。


确定 底层视图控制器

在将 这个应用程序 修改成 满足我们要求之前 我们 需要认识一下 Xcode 是如何使 这个项目 适应 标签栏功能的。

之前提到过 多视图应用程序的关键 是 底层视图控制器。在这个基于标签栏的应用程序当中 底层视图控制器 是 以UITabBarController类型物件的形式 出现的。正是 基于 这点,Xcode 在应用程序代理物件 加入了 一个UITabBarController类型的物件tabBarController。在这里这个例子中 应用程序代理物件 就是 TabBarAppDelegate类型的物件。我们 可以将 TabBarAppDelegate类型的物件 看成 应用程序本身。点选
TabBarAppDelegate.h这个文件,我们 可以看到 这样的语句:

123456789#import <UIKit/UIKit.h>@interface TabBarAppDelegate : UIResponder <UIApplicationDelegate, UITabBarControllerDelegate>@property (strong, nonatomic) UIWindow *window;@property (strong, nonatomic) UITabBarController *tabBarController;@end
从上面的语句 我们 可以看到 每个TabBarAppDelegate类型的物件 都包含 一个UIWindow *类型的变量window 用来存储 窗口物件的地址 和 一个UITabBarController *类型的变量tabBarController 用来存储 标签栏控制器物件的地址。

再 看看 内容视图控制器

在项目导航器中 我们 可以看到 Xcode 已经添加了 两类属于视图控制器的物件 用来 向用户 展现 内容。这两类物件 分别 是 TabBarFirstViewController 和 TabBarSecondViewController。这两类物件 都有 自己的.h文件、.m文件 和 相应的.xib文件。点击 TabBarFirstViewController.xib这个文件 我们 就可以看到 TabBarFirstViewController类型的物件 是 什么样子:

在TabBarFirstViewController类型的物件中 包含 一个视图物件。视图物件上 有 两个标签,上面的信息 用以提示 开发者。我们 可以在界面创建器里面 修改 这个视图 来满足 我们这个应用程序的要求。我们 先将 视图上的标签 删除。然后 点击 画布上的视图后 再点击 Xcode窗口右侧面板上方第四个标签:

从而 我们 进入了 属性查看器。在属性查看器中 我们 将 视图的背景颜色 修改为 黄色:

接着 我们 将 一个新的标签 拖、放 到视图中央。然后 双击 这个新的标签,在里面 输入 “视图一”然后 我们 点选 SecondViewController.xib这个文件 并且 重复 刚刚的步骤。这次 将 背景颜色 改成 浅蓝色,中央标签上的文字 写 “视图二”。

初始化 底层视图控制器

应用程序 启动时,会对 TabBarAppDelegate类型的物件 采取 application:didFinishLaunchingWithOptions:这项措施。我们 点选TabBarAppDelegate.m这个文件,然后 找到 application:didFinishLaunchingWithOptions:这项措施:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

-(BOOL)application:(UIApplication*)applicationdidFinishLaunchingWithOptions:(NSDictionary*)launchOptions

{

self.window=[[[UIWindowalloc]initWithFrame:[[UIScreenmainScreen]bounds]]autorelease];

//
Override point for customization after application launch.

UIViewController*viewController1=[[[TabBarFirstViewControlleralloc]initWithNibName:@"TabBarFirstViewController"bundle:nil]autorelease];

UIViewController*viewController2=[[[TabBarSecondViewControlleralloc]initWithNibName:@"TabBarSecondViewController"bundle:nil]autorelease];

self.tabBarController=[[[UITabBarControlleralloc]init]autorelease];

self.tabBarController.viewControllers=[NSArrayarrayWithObjects:viewController1,viewController2,nil];

self.window.rootViewController=self.tabBarController;

[self.windowmakeKeyAndVisible];

returnYES;

}

在这项措施中

1self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
这行语句中的[UIScreen mainScreen] 向 UIScreen这类物件 发送了 mainScreen这条消息,从而 获得了 主屏幕物件,然后 对 主屏幕物件 采取 bounds这项措施 从而 获得 主屏幕的尺寸 和 位置。接着 [UIWindow alloc] 为 UIWindow类型的物件,也就是 窗口物件,分配了 内存地址。而 initWithFrame:这项措施 利用 主屏幕的尺寸 和 位置 对 刚刚为窗口物件分配的地址 进行初始化。

1

2

3

UIViewController*viewController1=[[[TabBarFirstViewControlleralloc]initWithNibName:@"TabBarFirstViewController"bundle:nil]autorelease];

UIViewController*viewController2=[[[TabBarSecondViewControlleralloc]initWithNibName:@"TabBarSecondViewController"bundle:nil]autorelease];

这两行语句 分别 创建了 TabBarFirstViewController类型的物件viewController1 和 TabBarSecondViewController类型的物件viewController2。由于 TabBarFirstViewController 和 TabBarSecondViewController这两类物件 都属于 UIViewController类型,所以 viewController1 和 viewController2这两个物件的地址 可以存储
在UIViewController *类型的变量当中。创建 viewController1 和 viewController2这两个物件时,采取了 initWithNibName:bundle:这项措施。第一行中的initWithNibName:bundle: 适用于 TabBarFirstViewController类型的物件,第二行中的initWithNibName:bundle: 适用于 TabBarSecondViewController类型的物件。我们 可以在TabBarFirstViewController.m
和 TabBarSecondViewController.m这两个文件当中 看到 这两项initWithNibName:bundle:措施。initWithNibName:bundle:所附带的第一个参数 刚好 是 .xib文件的名称,viewController1 和 viewController2这两个物件 运行时 刚好 就是 我们在.xib文件中设计的样子。

1self.tabBarController = [[[UITabBarController alloc] init] autorelease];
这行语句 创建了 一个UITabBarController类型的物件 并 将 其地址 存储在TabBarAppDelegate类型物件所包含的变量tabBarController当中。

1

self.tabBarController.viewControllers=[NSArrayarrayWithObjects:viewController1,viewController2,nil];

这行语句 先向NSArray这类物件 发送了 arrayWithObjects:这条消息,创建了 一个NSArray类型的数组物件,并且 将 viewController1 和 viewController2这个两个物件的地址 添加 到这个数组物件当中;然后 将 这个数组物件的地址 存储 在tabBarController这个物件所包含的变量viewControllers当中。

1self.window.rootViewController = self.tabBarController;
这行语句 将 标签栏物件tabBarController的地址 存储 在窗口物件window所包含的变量rootViewController当中,从而 将 窗口window的底层视图控制器 设定为了 标签栏物件tabBarController。然后

1

[self.windowmakeKeyAndVisible];

这行语句 对TabBarAppDelegate所包含的窗口物件window 采取了 makeKeyAndVisible这项措施,使 这个窗口 呈现 在用户面前。

在创建viewController1这个物件时 我们 采取了 initWithNibName:bundle:这项措施,这项措施的第一个参数 是 .xib文件的名称。我们 点选 TabBarFirstViewController.m这个文件,然后 找到 initWithNibName:bundle:这项措施:

1234567891011121314151617- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{ self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { self.title = NSLocalizedString(@"First", @"First"); self.tabBarItem.image = [UIImage imageNamed:@"first"]; } return self;}
其中第一行语句

1

self=[superinitWithNibName:nibNameOrNilbundle:nibBundleOrNil];

对 initWithNibName:bundle:这项措施的实施对象 初始化。其中的关键字self 和 super 指的都是 initWithNibName:bundle:这项措施的实施对象。关键字self 特指 TabBarFirstViewController类型的物件,而 super 则特指 UIViewController类型的物件。

1if (self)
这行语句 判断 initWithNibName:bundle:这项措施的实施对象 是否为 空,如果 不为空的话,则执行 紧接着的两行语句。其中

1

self.title=NSLocalizedString(@"First",@"First");

这行语句 将 实施对象的标题 设定为 First,根据 这个例子的需要 我们 将 这行语句 改为:

1self.title = NSLocalizedString(@"视图一", @"视图一");
然后 我们 点击 TabBarSecondViewController.m这个文件,做出 同样的修改,只不过 将 Second 改成 视图二。编译 运行 这个程序后,我们 可以看到 如下的效果:

如果 我们 点击 第二个标签,就可以看到 浅蓝色的视图二了。

再 增加 一个视图

了解过 标签控制器 是如何 工作的,现在 我们 为这个应用程序 添加 我们自己的视图。第一步,我们 要创建 一类新的属于UIViewController类型的物件。首先 点击 Xcode的文件菜单,然后 点击 新文件。选择 弹窗右侧iOS标签之下的Cocoa Touch,然后 在弹窗左侧的区域 选择 Objective-C class后 点击 下一步。在新的弹窗中 将 物件类型名称TabBarThirdViewController 填写 在Class标签右侧的文本框中,再 将 物件类型名称UIViewController 填写 在Subclass of标签右侧的文本框中,这 表示 TabBarThirdViewController这类物件 也属于 UIViewController类型。 接着 勾选 With XIB for user interface选项后 点击 下一步,将 TabBarThirdViewController这类物件的文件 存放 在合适的位置。创建好 TabBarThirdViewController这类物件后,我们 点击 TabBarThirdViewController.xib这个文件,将 用户界面 载入 界面创建器。在界面创建器中 我们 将 视图的背景颜色 修改成 浅绿色,然后 将 一个新的标签 拖、放 到视图的中央 并且 将 标签上的文字 改为 “视图三”。接下来 我们 点击 TabBarThirdViewController.m这个文件,并且 找到 initWithNib:bundle:这项措施。然后 将 initWithNib:bundle:这项措施 修改成 下面这样:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

-(id)initWithNibName:(NSString*)nibNameOrNilbundle:(NSBundle*)nibBundleOrNil

{

self=[superinitWithNibName:nibNameOrNilbundle:nibBundleOrNil];

if(self){

self.title=NSLocalizedString(@"视图三",@"视图三");

self.tabBarItem.image=[UIImageimageNamed:@"first"];

}

returnself;

}

在这段代码中 我们 将 TabBarThirdViewController类型的视图控制器的标题 设定为了 视图三,并且 将 这个类型的视图控制器在标签栏中的图标 设定为 文件名为first的图片。向UIImage这类物件 发送 imageNamed:这条消息 就可以以某个图片文件为内容 创建 图片物件。

完成了 TabBarThirdViewController这类物件后,就应该 在应用程序启动时,创建 一个这种类型的物件 并且 将 其 添加 到标签栏控制器中。首先 我们 打开 TabBarAppDelegate.m这个文件。要适用 TabBarThirdViewController这类物件,我们 必须在TabBarAppDelegate.m这个文件中 导入 文件TabBarThirdViewController.h,我们 只需要 在@implementation命令上方 加入
下面这行语句 就行了:

1#import "TabBarThirdViewController.h"
然后 找到 application:didFinishLaunchingWithOptions:这项措施。在

1

UIViewController*viewController2=[[[TabBarSecondViewControlleralloc]initWithNibName:@"TabBarSecondViewController"bundle:nil]autorelease];

这行语句后 添加 下面这行语句:

1UIViewController *viewController3=[[[TabBarThirdViewController alloc] initWithNibName:@"TabBarThirdViewController" bundle:nil] autorelease];
从而 创建 TabBarThirdViewController类型的物件viewController3。接着 将

1

self.tabBarController.viewControllers=[NSArrayarrayWithObjects:viewController1,viewController2,nil];

这行语句 修改成

1

self.tabBarController.viewControllers=[NSArrayarrayWithObjects:viewController1,viewController2,viewController3,nil];

从而 将 viewController3这个物件 添加 到标签栏控制器tabBarController当中。

编译 并且 运行 这个程序后,我们 可以点击 标签栏中第三个标签,就可以看到 这样的效果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐