iOS应用开发
第一章 关于ios开发平台
1.iPhone技术层
Apple是以一系列层的方式来描述iPhone操作系统的实现技术,其中每层都由在应用程序中使用的不同框架组成,包括Cocoa Touch(触摸)、Media(媒体层)、Core Service(核心服务) 、Core OS。
Core OS和Core Service 层包括了一些iPhone OS的基础接口,可以访问文件,底层的数据等,这些接口大多是基于C语言的。
Media层包含了一些2D和3D的绘画、声音和影片。
Cocoa Touch层,大多数是基于objective-C的技术,这个架构提供了应用程序的一些基础架构和框架。
2.1 Cocoa Touch 层由多个框架组成,其中包括UIKit、Mapkit、Gamekit、Message UI/Address Book UI
UIKit 提供了大量的功能。它负责启动和关闭应用程序、控制界面和多点触摸事件。
Mapkit 提供了让开发人员在应用程序中添加地图视图,包括标记、定位和事件处理功能。
Gamekit 提供了iPhone应用程序的交互性,创建并使用对待网络的机制,包括绘画发现,仲裁和语言聊天。
Message UI/Address Book UI 框架提供了在任何应用程序中访问电子邮件的内容和联系人信息。
第二章 窗口、视图
1.什么是窗口和视图?
iPhone应用程序通常只有一个窗口,表示为一个UIWindow 的实例,应用程序在启动的时候将创建这个窗体。虽然iPhone OS 支持将一个窗体叠放在其他的窗口上方,但是应用程序永远不会创建多个窗口。
在 ios中,UIWindow的父类是UIView。视图是UIView的实例,负责在屏幕上定义一个矩形区域。视图可包含文件、图像等,视图在展示用户界面及相应用户界面交互方面发挥关键的作用。
2.如何创建一个窗口和视图?
2.1创建一个窗口,UIWindow对象
//创建一个window UIWindow *wd=[[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]]; //创建根视图 app_02ViewController *app_controller=[[app_02ViewController alloc]initWithNibName:@"app_02ViewController" bundle:nil]; wd.rootViewController=app_controller; //释放资源 [app_controller release]; //显示窗体 [wd makeKeyAndVisible];
|
2.2创建一个视图,UIView对象
//创建一个视图 UIView myView=[[UIView alloc]initWithFrame:CGRectMake(10, 10, 100, 100)]; //设置背景颜色 myView.backgroundColor=[UIColor greenColor]; //将创建的视图添加到父视图中 [self.view addSubview:myView];
//创建一个button UIButton *bt=[[UIButton alloc]initWithFrame:CGRectMake(100, 250, 80, 30)]; //设置button的背景颜色 bt.backgroundColor=[UIColor redColor]; //为button设置标题 [bt setTitle:@"button" forState:UIControlStateNormal]; //将button添加到window对象中 [wd addSubview:bt];
|
3.1动态添加/删除视图
添加视图的部分代码:
-(IBAction)onClickAdd:(id)sender //添加视图 { //创建一个视图对象 myView=[[UIView alloc]initWithFrame:CGRectMake(X, Y, 100, 100)]; //设置背景颜色 myView.backgroundColor=[UIColor redColor]; //将视图添加到父视图中 [self.view addSubview:myView]; //释放资源 [myView release]; //设置标记 myView.tag=count; X+=105; if (X>320) { X=20; Y+=120; } count++; } |
删除视图部分代码:
-(IBAction)onClickDelete:(id)sender //删除视图 { //通过tag值得到视图 UIView *myV=[self.view viewWithTag:count]; [myV removeFromSuperview]; count--;
// //得到当前视图的所有子视图 // NSArray *ay=[self.view subviews]; // for (UIView *V in ay) { //判断是否使Button,不是则移出 // if (![V isKindOfClass:[UIButton class]]) { // [V removeFromSuperview]; // } // } }
|
3.2实现一个简单的动画效果(视图变化)
首先我们在viewDidLoad方法中创建两个视图,
- (void)viewDidLoad { [super viewDidLoad]; //创建两个视图 UIView *v1=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 230, 230)]; UIView *v2=[[UIView alloc]initWithFrame:CGRectMake(0, 0, 230, 230)];
//为视图添加背景颜色 v1.backgroundColor=[UIColor redColor]; v2.backgroundColor=[UIColor blueColor]; //将视图添加到父视图中 [mainView addSubview:v1]; [mainView addSubview:v2]; } |
其次在我们自定义的事件中实现动画:
//实现动画 -(IBAction)onClickMove:(id)sender { //得到视图对象 UIView *v1=[mainView.subviews objectAtIndex:0]; UIView *v2=[mainView.subviews objectAtIndex:1];
//设置视图的透明度 v1.alpha=0.0; v2.alpha=1.0;
//设置开始动画 [UIView beginAnimations:nil context:nil]; //设置动画运行的轨迹,从外向里面 [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; //设置动画的持续时间 [UIView setAnimationDuration:2.0]; //触发动画,改变其属性 v1.alpha=1.0; v2.alpha=0.0; //通过改变位置关系产生动画 [UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:v2 cache:YES]; //改变子视图在主视图的位置 [mainView exchangeSubviewAtIndex:0 withSubviewAtIndex:1]
//完成动画 [UIView commitAnimations]; } |
3.3视图的旋转,一般情况下支持3中状态(Portrait 竖屏,Left横屏向左,Right 横屏向右),不支持home键向上。
这里需要实现视图控制器中的方法
部分实现代码:
//是否允许屏幕发生旋转 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations // return (interfaceOrientation == UIInterfaceOrientationPortrait); //表示始终竖屏 return YES; //返回YES允许
} |
//屏幕将要发生旋转时 - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { //竖屏 if (toInterfaceOrientation==UIInterfaceOrientationPortrait) { // btn1.frame = CGRectMake(33, 37, 101, 101); // btn2.frame = CGRectMake(191, 37, 101, 101); // btn3.frame = CGRectMake(33, 186, 101, 101); // btn4.frame = CGRectMake(191, 186, 101, 101); // btn5.frame = CGRectMake(33, 338, 101, 101); // btn6.frame = CGRectMake(191, 338, 101, 101); self.view=myView; self.view.transform = CGAffineTransformMakeRotation(0); self.view.frame = CGRectMake(0, 0, 320, 460); } //横屏向左 if (toInterfaceOrientation==UIInterfaceOrientationLandscapeLeft) { // btn1.frame = CGRectMake(20, 20, 101, 101); //btn2.frame = CGRectMake(20, 155, 101, 101); //btn3.frame = CGRectMake(177, 20, 101, 101); //btn4.frame = CGRectMake(177, 155, 101, 101); //btn5.frame = CGRectMake(328, 20, 101, 101); //btn5.frame = CGRectMake(328, 155, 101, 101); self.view=myView1; self.view.transform=CGAffineTransformMakeRotation(-M_PI_2); //-90度夹角 self.view.frame=CGRectMake(0, 0, 480, 300); } //横屏向右 if (toInterfaceOrientation==UIInterfaceOrientationLandscapeRight) { self.view=myView1; self.view.transform=CGAffineTransformMakeRotation(M_PI_2); //90度夹角 self.view.frame=CGRectMake(0, 0, 480, 300); } //向上 if (toInterfaceOrientation==UIInterfaceOrientationPortraitUpsideDown) { self.view=myView; self.view.transform = CGAffineTransformMakeRotation(0); self.view.frame = CGRectMake(0, 0, 320, 460); } }
|
第三章 高级GUI控件
1.使用导航栏控制器(Navigation Controller)
Navigation Controller 的功能是非常的强大,主要是用来切换多级的视图,可以将其理解为是一个栈, 这个栈中可以存放很多的View Controller,在这个栈创建的时候,我们首先给他添加一个View Controller,称之为Root View Controller(根视图控制器),同样存放在栈中,代表刚加载程序时显示的视图,当用户新选择的一个想要显示的视图时,那个新的View Controller入栈,它所控制的视图就会显示出来,这个新的View Controller称之为Sub Controller。
如何实现?
首先我们应该找到工程的AppDelegate.m文件,找到其 didFinishLaunchingwithOption:方法;
实现代码:
//创建一个导航视图控制器 UINavigationController *nav=[[UINavigationController alloc]initWithRootViewController:self.viewController ]; //将根视图指定为导航视图控制器 self.window.rootViewController = nav; [self.window makeKeyAndVisible]; [nav release]; |
实现一种页面之间的跳转功能,:
首先我们在工程中创建3个类,分别为RedViewController, BlueViewController, YellowViewController,当我们点击视图界面的跳转按钮,就将跳转到红色的界面,在按钮的点击事件中:
实现代码如下:
//创建一个视图控制器 RedViewController *red=[[RedViewController alloc]init]; //入栈操作 [self.navigationController pushViewController:red animated:YES]; [red release]; |
然后在RedViewController类的viewDidLoad中实现代码:
- (void)viewDidLoad { [super viewDidLoad]; self.title=@"red"; //创建一个对象,用于指定项 UIBarButtonSystemItem的系统项有很多种,一个枚举类型 UIBarButtonItem *item=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(onClickBlue)]; //设置导航的右边的项 self.navigationItem.rightBarButtonItem=item; //设置背景颜色 self.view.backgroundColor=[UIColor redColor]; } - (void)onClickBlue { //创建一个蓝色视图控制器对象 BlueViewController *blue=[[BlueViewController alloc]init]; //入栈,跳转到下一个视图控制器 [self.navigationController pushViewController:blue animated:YES]; [blue release]; }
|
BlueViewController类中的实现代码:
- (void)viewDidLoad { //设置导航栏的标题 self.title=@"blue"; [super viewDidLoad]; //隐藏左边的按钮 // [self.navigationItem setHidesBackButton:YES]; //隐藏导航栏 // [self.navigaionController.navigationBar setHidden:YES]; //创建对象 UIBarButtonItem *item1=[[UIBarButtonItem alloc]initWithTitle:@"返回" style:UIBarButtonItemStyleBordered target:self action:@selector(goBack)]; //指定项 self.navigationItem.rightBarButtonItem=item1; [item1 release]; } //点击导航栏中的返回按钮执行代码 - (void)goBack { //得到已经入栈的视图控制器 NSArray *ay=self.navigationController.viewControllers; //根据数组的下标返回上级的操作 [self.navigationController popToViewController:[ay objectAtIndex:0] animated:YES]; // popToRootViewControllerAnimated 返回根视图 }
|
当点击根视图的下一视图按钮时,我们需要在ViewController.m类中实现下面代码:
- (IBAction)click:(id)sender { //创建视图控制器对象 YellowViewController *ye=[[YellowViewController alloc]initWithTitle:@"返回"]; //设置模态视图的动画 ye.modalTransitionStyle=UIModalTransitionStylePartialCurl; //通过模态方式显示视图 [self.navigationController presentModalViewController:ye animated:YES]; [ye release]; }
//当点击黄色视图的返回按钮时,将返回到根视图界面 - (IBAction) onclick1:(id) sender { //返回原视图控制器 [self dismissModalViewControllerAnimated:YES]; } |
2.在导航栏中添加表格,首先我们应该创建一个数组,用于存放表格中的数据,要实现表格需要实现委托,UIViewController <UITabBarDelegate,UITableViewDataSource>,在.m文件中实现其必须方法,关键代码:
//提供行 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return [ay count]; }
//提供行数据 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //标记 static NSString *iden=@"cell"; //建立表格行数单元格 UITableViewCell *cell=[self.myTableView dequeueReusableCellWithIdentifier:iden]; if (cell==nil) { //创建单元格 cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:iden] autorelease]; } //显示数据 cell.textLabel.text=[ay objectAtIndex:indexPath.row]; //设置表格的详细按钮 cell.accessoryType=UITableViewCellAccessoryDetailDisclosureButton; return cell; } |
//详细按钮事件 - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath { CellViewController *cellView=[[CellViewController alloc]initWithTitle:[ay objectAtIndex:indexPath.row]]; //入栈操作 [self.navigationController pushViewController:cellView animated:YES]; [cellView release]; } |
3.创建一个UISegmentedControl ,以数组的形式存在,可以根据数组的下标获取视图控制器,
if ([seg selectedSegmentIndex]==0) { //设置导航栏控制器的风格 [self.navigationController.navigationBar setBarStyle:UIBarStyleBlack]; //黑色 }else if([seg selectedSegmentIndex]==1) { [self.navigationController.navigationBar setBarStyle:UIBarStyleBlackTranslucent];//透明色 }else { [self.navigationController.navigationBar setBarStyle:UIBarStyleDefault]; //默认,淡蓝色 } |
当点击后,导航栏视图控制器的风格发生了变化,当返回根视图时,其导航栏控制器风格变为默认状态.我们可以在视图将要显示时ViewWillAppear方法中实现.
//视图将要显示时 - (void)viewWillAppear:(BOOL)animated { //判断导航栏的样式 if (self.navigationController.navigationBar.barStyle==UIBarStyleBlackTranslucent) { self.navigationController.navigationBar.barStyle=UIBarStyleDefault; } } |
同时也可以使用委托模式的方法实现,实现<UINavigationControllerDelegate>协议,实现其可选方法:
//将要出现另一个导航栏控制器视图时发生 - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{ NSLog(@"viewController:%@",viewController); //判断该视图控制器是否是本类视图控制器的成员 if ([viewController isMemberOfClass:[self class]]) { //判断导航栏的样式 if (self.navigationController.navigationBar.barStyle==UIBarStyleBlackTranslucent) { self.navigationController.navigationBar.barStyle=UIBarStyleDefault; } } } |
4.工具栏的代码实现:
//创建一个工具栏控制器 UITabBarController *tabBar1=[[UITabBarController alloc]init];
//创建基本的视图控制器 RedViewController *redVC=[[RedViewController alloc]init]; BlueViewController *blueVC=[[BlueViewController alloc]init]; YellowViewController *yellowVC=[[YellowViewController alloc]init];
//创建导航栏控制器并指定对应的根视图控制器 UINavigationController *redNav=[[UINavigationController alloc]initWithRootViewController:redVC]; UINavigationController *blueNav=[[UINavigationController alloc]initWithRootViewController:blueVC]; UINavigationController *yelloNav=[[UINavigationController alloc]initWithRootViewController:yellowVC];
//创建数组用于存放导航栏控制器 NSArray *ay=[NSArray arrayWithObjects:redNav,blueNav,yelloNav,nil];
//显示工具栏和导航栏的标题 redVC.title=@"red"; blueVC.title=@"blue"; yellowVC.title=@"yellow"; //使用系统提供的工具栏项 UITabBarItem *item=[[UITabBarItem alloc]initWithTabBarSystemItem:UITabBarSystemItemMostViewed tag:100]; UITabBarItem *item1=[[UITabBarItem alloc]initWithTabBarSystemItem:UITabBarSystemItemMostRecent tag:101];
redVC.tabBarItem=item; blueVCbBarItem=item1;
//指定工具栏视图控制器 tabBar1.viewControllers=ay; //为根视图控制器指定视图 self.window.rootViewController=tabBar1; //self.window.rootViewController = self.tabBarViewController; [self.window makeKeyAndVisible]; //释放对象 [tabBar1 release]; [redNav release]; [blueNav release]; …... |
5.ios开发模式中的通知(NSNotification),一个通知的构成包括:通知的名称(name,是一个系统的常量),与通知相关联的对象(object)和用户信息(userInfo),在应用程序中通过类方法defaultCenter来访问通知中心.
如何注册一个通知?使用addObserver:方法,具体实现如下:
//addObserver 指定接收通知的对象,self表示自己(所在的视图控制器) //selector 收到通知后执行的方法 //name 通知消息的名称 //object 接收指定类发送的消息(nil:接收所有) //得到默认的通知中心.向通知中心注册消息 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(GetNotification:) name:@"mynotification" object:nil]; |
发送通知消息使用postNotificationName:方法
//创建消息内容 NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"电影",@"key1",@"游戏",@"key2", nil]; //发送通知消息(向通知中心发送一个名称为mynotification的消息) [[NSNotificationCenter defaultCenter] postNotificationName:@"mynotification" object:self userInfo:dic]; |
我们可以使用通知的模式实现自定义的键盘,首先需要注册通知,可以注册键盘弹出 UIKeyboardWillShowNotification 或隐藏 UIKeyboardWillHideNotification通知;
//注册键盘通知消息 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myKeyBoardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myKeyBoardWillHide:) name:UIKeyboardWillHideNotification object:nil]; |
部分实现代码:
//处理键盘消息通知 - (void) myKeyBoardWillShow:(NSNotification *) noti{ //执行选择方法后0.1,再显示键盘 [self performSelector:@selector(myKeyBoardShow:) withObject:nil afterDelay:0.1]; }
//自定义键盘 - (void) myKeyBoardShow:(NSNotification *) notifi{ UIWindow *myWinodw = nil;//存储键盘的窗体对象 UIView *myKb = nil; //存储键盘对象
myWinodw = [[[UIApplication sharedApplication] windows] objectAtIndex:1]; for (UIView *v in [myWinodw subviews]) { //判断视图的表述是否以<UIPeripheralHostView开头 if ([[v description] hasPrefix:@"<UIPeripheralHostView"]) { //得到虚拟键盘 myKb = [[v subviews] objectAtIndex:0]; break; } } if (myKb) { //添加自定义按钮 UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; [btn setTitle:@"清空" forState:UIControlStateNormal]; btn.frame = CGRectMake(0, 216-216/4, 320/3, 216/4); //添加按钮事件 [btn addTarget:self action:@selector(onclick) forControlEvents:UIControlEventTouchUpInside]; [myKb addSubview:btn]; } } |
得到一个应用程序的委托对象,实现代理模式:
//得到应用程序委托对象 app_10AppDelegate *app = [[UIApplication sharedApplication] delegate]; //实现委托 app.txtDelegate = self; |
第四章 触摸和手势编程
1.触摸是用户把手指放在屏幕上 ,触摸是一个UITouch对象,该对象放在UIEvent中,然后系统将UIEvent发送到应用程序上,最后,应用程序将UIEvent传递给一个合适的UIView,UIView是UIResponder的子类。
处理触摸的一系列的常用事件有:
//当手指首次触摸到屏幕时 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; //当手指在屏幕上移动时 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; //当手指离开屏幕时 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; //当触摸序列被电话呼入所打断,取消时 - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event |