http://www.iphonedevcentral.com/create-uitabbarcontroller/
Create a UITabBarController from scratch
Tab bar based apps are probably as common as table-based apps and it’s even more common to see them combined. That’s what we’re going to do in this tutorial.
There is a very easy way of creating a tab bar application. In fact, it’s so easy it requires no work whatsoever. When you choose to create a new iPhone application in Xcode, one of the options is
Tab Bar Application.
Just the bare-bones template provided by Apple gives you a fully-functioning app with two tabs. That is not what this tutorial will be about. We are going to create a tab bar controller programatically. It’s really a lot easier than most people think.
Prerequisites
This tutorial is a continuation of my
previous tutorials
so if you haven’t followed them, it’s a good time to catch up.
We’re going to be starting off from a slightly modified version of the previous source code. You can download the primer code for this tutorial here:MyDVDLibrary04Primer
. The only changes made were some name changes (DetailViewController
became
DvdInfoViewController
) and I organized all classes into groups.
Also, I’ve recently upgraded to OS X Snow Leopard + Xcode 3.2 with iPhone SDK 3.0 (not 3.1 yet) so the project was compiled on that platform.
1. Create DetailViewTabBarController class
We’re going to add a view controller that will create a tab bar controller with three tabs: Info, Stats and Borrowers. Each of the tabs will be a separate, self-contained view controller. We already created one of them,
DvdInfoViewController
, which was previously called
DetailViewController
. The reason I renamed it is that the real detail view controller will now be our tab bar controller.
In Xcode, right-click on the
View Controllers
folder from the the
Groups & Files
panel on the left and choose
Add -> New File
. Choose
UIViewController subclass
from the
Cocoa Touch Class section
and click
Next
. Name the file
DetailViewTabBarController
.
Note: You may be wondering why we didn’t choose a UITabBarController subclass instead. As you can see that option wasn’t even offered. This is because UITabBarController is not meant to be subclassed. Instead, we create a generic view controller to which a tab bar controller will be assigned.
2. Create DvdStatsViewController and DvdBorrowersViewController
These are the new view controllers I mentioned previously. We already have our
DvdInfoViewController
that will be in the first tab, so let’s create the remaining two.
In Xcode, right-click on the View Controllers
folder and choose Add -> New File
. Choose UIViewController subclass
and name the file DvdStatsViewController
.
To create
DvdBorrowersViewController
do the same thing, only name it
DvdBorrowersViewController
.
That’s it about those two controllers for now. I’m not going to cover actually filling them with any content since that’s not the point of this tutorial. We will leave them here as placeholders for future tutorials when we cover Core Data and RSS feed processing.
3. Set up DetailViewTabBarController
Since we’re going to be coming to the tab bar controller from the
RootViewController
, we need to pass it DVD info from the row that was tapped. We can do that in a custom init method in
DetailViewTabBarController
. You’ll see how it’s used later when we instantiate it in
didSelectRowAtIndexPath
method ofRootViewController
.
We’re also going to need a handle on the data about the DVD that was tapped on the front page.
Declare it all in
DetailViewTabBarController.h
@interface DetailViewTabBarController : UIViewController {
NSDictionary *dvdData;
}
-(id)initWithDvdData:(NSDictionary *)data;
@end
Next, let’s define
initWithDvdData
in
DetailViewTabBarController.m
-(id)initWithDvdData:(NSDictionary *)data {
if (self = [super init]) {
dvdData = data;
}
return self;
}
All we’re doing here is setting local instance variable
dvdData
to whatever is passed in. We now have a handle on the DVD data and can use it across all the view controllers.
4. Implement loadView method in DetailViewTabBarController
loadView
is a method on UIViewController that can be overridden in case you want to build your view from ground up. That’s exactly what we want to do so let’s override
loadView
now. Let’s discuss it piece by piece;
- (void)loadView {
UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
contentView.backgroundColor = [UIColor whiteColor];
self.view = contentView;
[contentView release];
Borrowing the biblical line; in the beginning there was nothing, we need a base view to build upon. So we created an empty view with a white background that takes up the whole screen. We will attach all the other views to it.
Now we need to instantiate all three of our controllers. Each one will become one tab in the tab view.
// Declare all three view controllers
DvdInfoViewController *dvdInfoController = [[DvdInfoViewController alloc]
initWithDvdData:dvdData
nibName:@"DetailViewController" bundle:[NSBundle mainBundle]];
DvdStatsViewController *dvdStatsViewController = [[DvdStatsViewController alloc] init];
DvdBorrowersViewController *dvdBorrowersViewController = [[DvdBorrowersViewController alloc] init];
// Set a title for each view controller. These will also be names of each tab
dvdInfoController.title = @"Info";
dvdStatsViewController.title = @"Stats";
dvdBorrowersViewController.title = @"Borrowers";
You see the
dvdInfoController
is initialized the same way we did it before in
RootViewController
. We pass it
dvdData
that we get from our custom initialization method.
Now the meat of this method, let’s create the actual tab bar controller and give it the three view controllers. You can note that we’re setting the bounding frame to be 320 pixels wide and 460 pixels high. We shave off 20 pixels because the title bar is already taking up, well, 20 pixels.
UITabBarController creates tabs when you call setViewControllers on it and pass it an array with your controllers in it. That’s what’s happening here.
// Create an empty tab controller and set it to fill the screen minus the top title bar
UITabBarController *tabBarController = [[UITabBarController alloc] init];
tabBarController.view.frame = CGRectMake(0, 0, 320, 460);
// Set each tab to show an appropriate view controller
[tabBarController setViewControllers:
[NSArray arrayWithObjects:dvdInfoController, dvdStatsViewController, dvdBorrowersViewController, nil]];
And finally, let’s clean up objects we no longer need from memory and add the tab controller view to our parent view so we can actually see it.
// Clean up objects we don't need anymore
[dvdInfoController release];
[dvdStatsViewController release];
[dvdBorrowersViewController release];
// Finally, add the tab controller view to the parent view
[self.view addSubview:tabBarController.view];
}
5. Modify RootViewController’s didSelectRowAtIndexPath method to display DetailViewTabBarController
The last step we need to take is to modify
didSelectRowAtIndexPath
in
RootViewController
to display our newly created tab bar controller instead of theDvdInfoViewController
we showed in the last tutorial.
Open up
RootViewController.m
and modify
didSelectRowAtIndexPath
to look like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DetailViewTabBarController *controller = [[DetailViewTabBarController alloc]
initWithDvdData:[dao libraryItemAtIndex:indexPath.row]];
controller.title = [[dao libraryItemAtIndex:indexPath.row] valueForKey:@"title"];
[self.navigationController pushViewController:controller animated:YES];
[controller release];
}
At this point, you can run your project and tapping on a DVD title should take you to the tab bar controller which has three tabs. The first tab contains the movie info, the remaining two are empty. As I mentioned before, we’ll fill those in in the later tutorials or it can be left as an exercise for the reader.
6. Add icon to tabs
The tabs now only have a textual title. Let’s make it prettier by adding an icon to each of them. I only use one image (included in the project) for demonstration purposes but you can have a different image for each tab. The image should be 32×32 pixels PNG file. You don’t need to to create the pretty, shiny, gray and blue images. Just pass it a normal image and the SDK will do the rest.
Add this in the
loadView
method in
DetailViewTabBarViewController.m
implementation file right after we set the titles of the controllers:
// Set a title for each view controller. These will also be names of each tab
dvdInfoController.title = @"Info";
dvdStatsViewController.title = @"Stats";
dvdBorrowersViewController.title = @"Borrowers";
dvdInfoController.tabBarItem.image = [UIImage imageNamed:@"dvdicon.png"];
dvdStatsViewController.tabBarItem.image = [UIImage imageNamed:@"dvdicon.png"];
dvdBorrowersViewController.tabBarItem.image = [UIImage imageNamed:@"dvdicon.png"];
If everything went well, you should see your app looking like this
Conclusion
While it may seem easier to create everything in the Interface Builder, you can see that in this case creating a tab bar controller was a breeze. Adding new tabs/view controllers to it is as easy as adding an object to an array. I hope this tutorial connecting the dots how to go from a table view to a tab bar view in a navigation-based application.
You can download the complete source code to this tutorial here:
My DVD Library Tutorial 4
分享到:
相关推荐
毕业论文-叮当活动报名V1.0.0 开源版-整站商业源码.zip
c#随机输出14个字符串代码.zip
内容概要:文章主要探讨了批量工件并行切割下料的问题,重点在于优化切割方案以提高板材利用率、减少切割时间和降低能耗。文中详细介绍了切割机的工作原理及其运动方式,以及对不同尺寸板材(A: 8000*3000、B: 6000*2000、C: 7000*2500)的切割要求。提出了五个任务:一是不考虑约束条件下,为三种板材设计切割排版方案以最大化板材利用率;二是基于四把切割刀具,规划最短时间完成切割的协同运行方案;三是根据附件2提供的工件型号分布,确定切割这批工件所需的板材数量和排版方案,以最大化板材利用率;四是使用八把切割刀具,在保证板材利用率不低于之前方案95%的前提下,最小化切割时间;五是综合考虑板材、设备时间和能量的成本,利用最多十把切割刀具,最小化总成本。;
**描述:“适用于JDK8的环境”** 本文将深入探讨Neo4j社区版3.5.6版本,这是一个基于图数据库的强大工具,特别适用于知识图谱构建和可视化。由于其运行需求,必须在Java Development Kit(JDK)8的环境下进行安装和操作。 **一、Neo4j概述** Neo4j是一款开源的图形数据库,它以节点、关系和属性的形式存储数据,这使得处理复杂网络结构的数据变得更为直观和高效。Neo4j社区版是免费的,适合开发和学习用途,而企业版则提供了更多的高级功能和服务。 **二、JDK8要求** 为了运行Neo4j 3.5.6,你需要在你的计算机上安装JDK8。JDK是Java开发工具包,包含了运行Java应用程序所需的Java虚拟机(JVM)以及一系列开发工具。确保安装的是与Neo4j版本兼容的JDK版本至关重要,因为不兼容的JDK可能会导致运行错误或性能问题。 **三、安装和配置** 1. **下载与解压**: 从官方渠道下载"neo4j-community-3.5.6.zip"压缩文件,并将其解压到你选择的目录。 2. **环境变量配置**: 配置系统环境变量,将Neo4j的bin目录添加到PATH环境变量中,以便于命令行启动和管理数据库。 3. **修改配置文件**: Neo4j的配置主要通过`conf/neo4j.conf`文件进行,如需更改默认设置,如内存分配、端口设置等,应在此文件中进行修改。 4. **启动和停止**: 使用`neo4j console`命令启动服务,`neo4j stop`命令关闭服务。 **四、知识图谱与可视化** Neo4j因其强大的图数据模型,成为构建知识图谱的理想选择。你可以使用Cypher查询语言来操作和查询图数据,它的语法简洁且直观,易于学习。 1. **Cypher语言**: Cypher是一种声明式、图形化
flatbuffers/////
AGV技术详解.pdf
内容概要:本文介绍了Protozoa,一种基于WebRTC的多媒体隐蔽传输工具,旨在帮助用户绕过互联网审查。Protozoa利用WebRTC视频通话作为载体,通过修改WebRTC框架中的编码视频帧来嵌入并传输隐蔽数据。它具有高带宽性能(可达1.4Mbps)和强大的流量分析抗性,能够在不被检测的情况下传输任意IP流量。实验表明,Protozoa可以在不同网络条件下保持稳定性能,并成功绕过中国、俄罗斯和印度的国家级审查机制。 适合人群:对网络安全、隐蔽通信技术感兴趣的科研人员和技术专家,以及需要绕过互联网审查访问受限内容的用户。 使用场景及目标:①适用于希望在受限制网络环境中安全、隐蔽地访问互联网资源的技术人员;②研究和测试新型隐蔽通信方法的研究人员;③评估和改进隐蔽通信系统的安全性和性能。 阅读建议:由于涉及复杂的网络协议和技术细节,建议读者具备一定的计算机网络和编程基础。重点关注Protozoa的工作原理、实现方式及其与现有隐蔽通信工具的比较,以便更好地理解和应用这一技术。
毕业论文-发卡-整站商业源码.zip
实训商业源码-智答-更好用的语音问答6.0.4-毕业设计.zip
实训商业源码-免签码支付源码-毕业设计.zip
毕业论文-房产中介小程序8.0.56+开源版-整站商业源码.zip
毕业论文-活动报名小程序-整站商业源码.zip
ANSYS产品资料——Systems and Multiphysics.pdf
毕业论文-KTV小程序V1.6.1+分销1.0.0带前端-整站商业源码.zip
该项目实现了一个多目标优化算法的集成框架,主要用于求解复杂的多目标优化问题(MOPs)。其核心功能包括以下方面: 1. **多目标优化算法集成** 项目整合了三种经典的多目标优化算法: - **NSGA-II**:基于非支配排序和拥挤度距离的遗传算法,适用于全局搜索。 - **MOPSO**:多目标粒子群算法,通过粒子群协同搜索和外部存档维护Pareto前沿。 - **NSGAMOPSO**:创新性地结合NSGA-II和MOPSO的双种群协同进化策略,兼顾全局探索与局部开发能力。 2. **测试函数库与问题定义** 提供了47个标准多目标测试函数(如ZDT、DTLZ、UF、WFG系列等)和实际工程问题(如盘式制动器设计),支持2-3目标优化,并内置真实Pareto前沿数据用于性能验证。 3. **性能评估指标** 实现了四种评价指标: - **IGD**(反向世代距离):衡量解集与真实Pareto前沿的接近程度。 - **GD**(世代距离):评估解集的收敛性。 - **HV**(超体积):量化解集的多样性和覆盖范围。 - **Spacing**:反映解集分布的均匀性。 4. **可视化与对比分析** 支持二维/三维Pareto前沿的动态绘图,直观对比不同算法的优化效果,并自动生成指标数据表格(如Excel文件),便于量化分析算法性能。 5. **自适应参数与约束处理** 算法参数(如交叉概率、变异概率)可动态调整,同时通过边界检查和修复机制确保解的可行性。 **应用价值**:该项目为研究者和工程师提供了一个高效、可扩展的多目标优化工具,适用于学术研究、工业设计(如机械优化)等领域,能够快速验证算法性能并解决实际多目标优化问题。
AVEVA数字时代的智造方式.pdf
毕业论文-叮咚同城微圈小程序V11.3.3+前端 开源版-整站商业源码.zip
内容概要:文章详细探讨了基于MATLAB/Simulink的电动汽车预充电路设计,旨在解决电动汽车启动及充电初始阶段电池系统承受瞬态大电流冲击的问题。文章首先分析了电动汽车技术的发展背景及预充电路的重要性,接着介绍了预充电路的工作原理、设计要点及相关的技术标准。文中通过构建预充电路的MATLAB/Simulink仿真模型,对比了不同预充电阻值对电流冲击的影响,并引入PID控制策略优化预充电过程。最终,通过多工况仿真验证了设计方案的工程适用性和有效性。研究结果显示,优化后的预充电路可将冲击电流峰值抑制在安全阈值范围内,电压过渡过程的稳定性提升35%以上。 适合人群:具备一定电力电子和控制理论基础的电气工程师、从事电动汽车研发的技术人员、高校相关专业的研究生及科研人员。 使用场景及目标:①研究电动汽车预充电路的动态特性及关键参数优化;②设计智能控制策略以提升充电系统的安全性与效率;③验证预充电路在不同工况下的性能表现,为实际应用提供技术支持。 其他说明:本文不仅提供了详细的理论分析和仿真模型构建方法,还展示了仿真实验的具体步骤和结果,强调了预充电路设计对电动汽车整体性能和安全性的关键作用。研究成果不仅适用于锂离子电池预充场景,其多变量控制思路亦可扩展至钠离子电池、固态电池等新型储能系统的充放电管理领域。
毕业论文-超好看的导航源码-整站商业源码.zip