集合视图控制器(CollectionViewController) 、 标签控制器(TabBarController) 、 高级控件介绍...

 

1 创建集合视图,设置相关属性以满足要求

1.1 问题

集合视图控制器UIConllectionViewController是一个展示大量数据的控制器,系统默认管理着一个集合视图UICollectionView,功能几乎和UITableViewController差不多,能够以多行多列的形式展示数据。

集合视图UICollectionView继承至UIScrollView,也同tableView一样有两个协议,分别是UICollectionViewDataSource数据源协议和UICollectionViewDelegate委托协议,本案例将学习如何使用UICollectionView来展示数据,如图-1所示:

图-1

1.2 方案

首先创建一个SingleViewApplication项目,然后创建一个TRMyCollectionViewController集合视图控制器,该视图控制器继承至UICollectionViewController,然后在TRAppDelegate中创建一个带有导航的TRMyCollectionViewController集合视图控制作为根视图控制器。

其次在xib文件删除自动生成的View视图,增加一个CollectionView视图,并将File’s Owner的view属性连线到CollectionView,同时也将collectionView的dataSource和delegate进行连线。

在xib中选中collectionView在右边栏的检查器中设置collectionView的各种属性,包括单元格的宽高、分区的边距,单元格之间的间距,滚动方向等。

然后创建一个带有xib文件的TRMyCell类,该类继承至UICollectionViewCell,UICollectionViewCell是集合视图的单元格类,是集合视图的重要组成部分,与表视图的单元格不同,由于集合视图的单元格没有系统定义好的内容视图和辅助视图,所以集合视图的单元格通常都需要自定义。

最后在TRMyCollectionViewController中注册集合视图的单元格,然后实现集合视图的协议方法,给集合视图加载数据。

1.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建TRMyCollectionViewController类

在Xcode项目中创建一个TRMyCollectionViewController集合视图控制器,该视图控制器继承至UICollectionViewController,然后在TRAppDelegate中创建一个带有导航的TRMyCollectionViewController集合视图控制作为根视图控制器,代码如下所示:

  1. -(BOOL)application:(UIApplication *)application 
  2. didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  3. {
  4. self.window [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  5. self.window.backgroundColor [UIColor whiteColor];
  6. TRMyCollectionViewController *myCVC [[TRMyCollectionViewController alloc]initWithNibName:@"TRMyCollectionViewController" bundle:nil];
  7. UINavigationController *navi [[UINavigationController alloc]initWithRootViewController:myCVC];
  8. self.window.rootViewController = navi;
  9. [self.window makeKeyAndVisible];
  10. return YES;
  11. }

步骤二:在xib文件中设置集合视图

将xib文件中的view视图删除,从对象库中拖拽一个CollectionView到xib中,注意不要选成了CollectionViewController,如图-2所示:

图-2

然后将File’s Owner的view属性连线到CollectionView,同时也将collectionView的dataSource和delegate进行连线,如图-3所示:

图-3

最后在右边栏的第五个检查器中设置collectionView的相关属性,包括单元格的宽高,分区的边距以及单元格之间的间距等,如图-4所示:

图-4

由于UICollectionView是继承至UIScrollView,所以也可以滚动,默认的滚动方向是垂直的,也可以通过右边栏的第四个检查器将滚动方向设置为水平的,如图-5所示:

图-5

步骤三:创建单元格类TRMyCell,自定义集合视图单元格

创建一个带有xib文件的TRMyCell类,该类继承至UICollectionViewCell,在xib文件中拖放一个Label控件到CollectionViewCell中,并设置Label的相关属性,如图-6所示:

图-6

将Label控件关联成TRMyCell的公开属性displayLabel,代码如下所示:

  1. @interface TRMyCell : UICollectionViewCell
  2. @property (weak, nonatomicIBOutlet UILabel *displayLabel;
  3. @end

然后在TRMyCollectionViewController中导入头文件“TRMyCell.h”,并且在viewDidLoad方法里面注册cell,代码如下所示:

  1. //定义个cell标识
  2. static NSString *cellIdentifier = @"MyCell";
  3. (void)viewDidLoad
  4. {
  5. [super viewDidLoad];
  6. self.title = @"CollectionView";
  7. //注册cell
  8. [self.collectionView registerNib:[UINib nibWithNibName:@"TRMyCell" bundle:nil] forCellWithReuseIdentifier:cellIdentifier];
  9. }

步骤四:实现集合视图的协议方法,加载数据

首先实现集合视图的协议方法numberOfSectionsInCollectionView:告诉集合视图需要显示的分区数,代码如下所示:

  1. (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
  2. {
  3. return 15;
  4. }

然后实现协议方法告诉集合视图每个分区需要显示的单元格数,如图-6所示:

  1. -(NSInteger)collectionView:(UICollectionView *)collectionView 
  2. numberOfItemsInSection:(NSInteger)section
  3. {
  4. return 10;
  5. }

最后实现协议方collectionView:cellForItemAtIndexPath:告诉集合视图需要显示的内容。同表视图一样在该方法里面使用dequeueReusableCellWithReuseIdentifier:forIndexPath:方法创建cell对象,并且根据indexPath参数设置每个cell的显示内容,代码如下所示:

  1. -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView 
  2. cellForItemAtIndexPath:(NSIndexPath *)indexPath
  3. {
  4. TRMyCell *cell [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
  5. cell.displayLabel.text [NSString stringWithFormat:@"%d",indexPath.row];
  6. cell.backgroundColor [UIColor colorWithRed:0 green:1 blue:0 alpha:indexPath.row 0.1];
  7. return cell;
  8. }

1.4 完整代码

本案例中,TRAppDelegate.m文件中的完整代码如下所示:

 
  1. #import "TRAppDelegate.h"
  2. #import "TRCustomLayoutCollectionViewController.h"
  3. @implementation TRAppDelegate
  4. -(BOOL)application:(UIApplication *)application 
  5. didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  6. self.window [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  7. self.window.backgroundColor [UIColor whiteColor];
  8. TRCustomLayoutCollectionViewController *myCVC [[TRCustomLayoutCollectionViewController alloc]initWithNibName:@"TRCustomLayoutCollectionViewController" bundle:nil];
  9. UINavigationController *navi [[UINavigationController alloc]initWithRootViewController:myCVC];
  10. self.window.rootViewController = navi;
  11. [self.window makeKeyAndVisible];
  12. return YES;
  13. }
  14. @end
 

本案例中,TRMyCollectionViewController.m文件中的完整代码如下所示:

 
  1. #import "TRMyCollectionViewController.h"
  2. #import "TRMyCell.h"
  3. @implementation TRMyCollectionViewController
  4. //定义个cell标识
  5. static NSString *cellIdentifier = @"MyCell";
  6. (void)viewDidLoad
  7. {
  8. [super viewDidLoad];
  9. self.title = @"CollectionView";
  10. //注册cell
  11. [self.collectionView registerNib:[UINib nibWithNibName:@"TRMyCell" bundle:nil] forCellWithReuseIdentifier:cellIdentifier];
  12. }
  13. (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
  14. {
  15. return 15;
  16. }
  17. -(NSInteger)collectionView:(UICollectionView *)collectionView 
  18. numberOfItemsInSection:(NSInteger)section
  19. {
  20. return 10;
  21. }
  22. (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView 
  23. cellForItemAtIndexPath:(NSIndexPath *)indexPath
  24. {
  25. TRMyCell *cell [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
  26. cell.displayLabel.text [NSString stringWithFormat:@"%d",indexPath.row];
  27. cell.backgroundColor [UIColor colorWithRed:0 green:1 blue:0 alpha:indexPath.row 0.1];
  28. return cell;
  29. }
  30. @end
 

本案例中,TRMyCell.h文件中的完整代码如下所示:

 
  1. #import<UIKit/UIKit.h>
  2. @interface TRMyCell : UICollectionViewCell
  3. @property (weak, nonatomicIBOutlet UILabel *displayLabel;
  4. @end
 

2 使用布局创建集合视图

2.1 问题

CollectionView的布局是其精髓,相当于CollectionView的大脑和中枢,负责设置CollectionView的一些属性,包括位置、尺寸、透明度、层级关系、形状等,本案例将使用集合视图的布局用代码创建一个集合视图,如图-7所示:

图-7

2.2 方案

UICollectionViewFlowLayout布局类是UICollectionViewLayout类的子类,称为流式布局类,所有的单元格都依次挨着摆放。

首先创建一个SingleViewApplication项目,然后创建一个带有导航的TRCustomLayoutCollectionViewController视图控制器作为根视图控制器,该视图继承至UIViewController。

其次在viewDidLoad方法里面创建一个UICollectionViewFlowLayout布局对象,设置布局对象的各种属性。

然后在viewDidLoad方法里面创建集合视图对象collectionView,使用初始化方法initWithFrame:collectionViewLayout:进行初始化,collectionViewLayout:所传递的参数就是上一步所创建的布局对象。

最后注册集合视图的cell,TRCustomLayoutCollectionViewController遵守集合视图协议,并且实现协议方法给集合视图加载数据。

2.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建集合视图项目

在Xcode项目中创建一个TRCustomLayoutCollectionViewController视图控制器类,继承至UIViewController。然后在TRAppDelegate中创建一个带有导航的TRCustomLayoutCollectionViewController视图控制器作为根视图控制器,代码如下所示:

 
  1. -(BOOL)application:(UIApplication *)application 
  2. didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  3. {
  4. self.window [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  5. self.window.backgroundColor [UIColor whiteColor];
  6. TRCustomLayoutCollectionViewController *myCVC [[TRCustomLayoutCollectionViewController alloc]initWithNibName:@"TRCustomLayoutCollectionViewController" bundle:nil];
  7. UINavigationController *navi [[UINavigationController alloc]initWithRootViewController:myCVC];
  8. self.window.rootViewController = navi;
  9. [self.window makeKeyAndVisible];
  10. return YES;
  11. }

步骤二:创建UICollectionViewFlowLayout布局对象

首先在viewDidLoad方法里面创建集合视图对象collectionView,使用初始化方法initWithFrame:collectionViewLayout:进行初始化,frame:所传递的参数就是屏幕的大小,collectionViewLayout:所传递的参数就是上一步所创建的布局对象,代码如下所示:

 
  1. //创建集合视图的布局对象
  2. UICollectionViewFlowLayout *layout [[UICollectionViewFlowLayout alloc]init];
  3. //设置每个cell的大小
  4. layout.itemSize CGSizeMake(150150);
  5. //设置每个cell之间的间距
  6. layout.minimumInteritemSpacing 10;
  7. //设置每个分局的边距
  8. layout.sectionInset UIEdgeInsetsMake(1502015020);
  9. //设置滚动方向为水平方向
  10. layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;

步骤三:创建集合视图对象collectionView

在xib界面上拖拽一个UISlider控件,在右边栏的第四个检查器中将miniMum、maxiMum和current分别设置为0、1和0,然后将slider关联成TRViewController的方法sliderValueChange:,该方法主要实现功能是拖动滑块能控制tableView1在界面中的显示第几行单元格,在方法里面根据slider的value值计算出tableView的contentOffset即可,代码如下所示:

  1. //创建集合视图对象
  2. CGSize screenSize [[UIScreen mainScreen] bounds].size;
  3. UICollectionView *collectionView [[UICollectionView alloc]initWithFrame:CGRectMake(00, screenSize.width, screenSize.height) collectionViewLayout:layout];

然后设置collectionView的数据源对象和委托对象,并添加到父视图中,代码如下所示:

 
  1. //设置collectionView的委托对象
  2. collectionView.dataSource = self;
  3. collectionView.delegate = self;
  4. //将集合视图添加到父视图中
  5. [self.view addSubview:collectionView];

步骤四:遵守委托协议,实现协议方法

首先在viewDidLoad方法里面注册集合视图的单元格,本案例没有使用自定义的cell,而是直接使用系统提供的UICollectionViewCell,所以使用方法registerClass:forCellWithReuseIdentifier:进行注册,registerClass:参数传递的是UICollectionViewCell类,代码如下所示:

 
  1. //在viewDidLoad方法外面定义cell的注册标识
  2. static NSString *cellIdentifier = @"MyCell";
  3. //在viewDidLoad方法里面进行cell的注册
  4. [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:cellIdentifier];

然后TRCustomLayoutCollectionViewController遵守集合视图协议,并且实现协议方法给集合视图加载数据,代码如下所示:

 
  1. //遵守集合视图的数据源协议和委托协议
  2. @interface TRCustomLayoutCollectionViewController () <UICollectionViewDataSource, UICollectionViewDelegate>
  3. @end
  4. (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
  5. {
  6. return 10;
  7. }
  8. -(NSInteger)collectionView:(UICollectionView *)collectionView 
  9. numberOfItemsInSection:(NSInteger)section
  10. {
  11. return 6;
  12. }
  13. -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView 
  14. cellForItemAtIndexPath:(NSIndexPath *)indexPath
  15. {
  16. UICollectionViewCell *cell [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
  17. cell.backgroundColor [UIColor grayColor];
  18. return cell;
  19. }

2.4 完整代码

本案例中,TRAppDelegate.m文件中的完整代码如下所示:

 
  1. #import "TRAppDelegate.h"
  2. #import "TRViewController.h"
  3. @implementation TRAppDelegate
  4. -(BOOL)application:(UIApplication *)application 
  5. didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  6. {
  7. self.window [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  8. self.window.backgroundColor [UIColor whiteColor];
  9. TRViewController *vc [[TRViewController alloc]initWithNibName:@"TRViewController" bundle:nil];
  10. UINavigationController *navi [[UINavigationController alloc]initWithRootViewController:vc];
  11. self.window.rootViewController = navi;
  12. [self.window makeKeyAndVisible];
  13. return YES;
  14. }
  15. @end
 

本案例中,TRCustomLayoutCollectionViewController.m文件中的完整代码如下所示:

 
  1. #import "TRCustomLayoutCollectionViewController.h"
  2. //遵守集合视图的数据源协议和委托协议
  3. @interface TRCustomLayoutCollectionViewController () <UICollectionViewDataSource, UICollectionViewDelegate>
  4. @end
  5. @implementation TRCustomLayoutCollectionViewController
  6. //在viewDidLoad方法外面定义cell的注册标识
  7. static NSString *cellIdentifier = @"MyCell";
  8. (void)viewDidLoad
  9. {
  10. [super viewDidLoad];
  11. UICollectionViewFlowLayout *layout [[UICollectionViewFlowLayout alloc]init];
  12. //设置每个cell的大小
  13. layout.itemSize CGSizeMake(150150);
  14. //设置每个cell之间的间距
  15. layout.minimumInteritemSpacing 10;
  16. //设置每个分局的边距
  17. layout.sectionInset UIEdgeInsetsMake(1502015020);
  18. //设置滚动方向为水平方向
  19. layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
  20. //创建集合视图对象
  21. CGSize screenSize [[UIScreen mainScreen] bounds].size;
  22. UICollectionView *collectionView [[UICollectionView alloc]initWithFrame:CGRectMake(00, screenSize.width, screenSize.height) collectionViewLayout:layout];
  23. //设置collectionView的委托对象
  24. collectionView.dataSource = self;
  25. collectionView.delegate = self;
  26. //将集合视图添加到父视图中
  27. [self.view addSubview:collectionView];
  28. //由于直接使用的系统的UICollectionViewCell,注册cell使用registerClass:方法
  29. [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:cellIdentifier];
  30. }
  31. (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
  32. {
  33. return 10;
  34. }
  35. -(NSInteger)collectionView:(UICollectionView *)collectionView 
  36. numberOfItemsInSection:(NSInteger)section
  37. {
  38. return 6;
  39. }
  40. -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView 
  41. cellForItemAtIndexPath:(NSIndexPath *)indexPath
  42. {
  43. UICollectionViewCell *cell [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
  44. cell.backgroundColor [UIColor grayColor];
  45. return cell;
  46. }
  47. @end
  48. 3 使用TabBar管理多个VC及Navi

3.1 问题

UITabbarController同导航控制器一样是一个控制器的控制器,标签栏位于屏幕下方,占有49个像素,本案例将学习如何使用标签控制器来管理视图控制器,如图-8所示:

图-8

3.2 方案

首先同样创建一个SingleViewApplication项目,然后创建三个带有xib的视图控制器类TRFirstViewController、TRSecondViewController,TRThirdViewController,作为标签控制器所管理的子控制器。

然后在TRAppDelegate的程序入口方法中分别创建三个带有导航子视图控制器对象,再创建一个UITabbarController对象tabbar,将三个视图控制器对象设置为tabbar的子视图控制器,屏幕下方的标签栏就回有三个按钮对应三个子视图控制。

通常为了点击方便一般管理的子视图控制器不超过五个,如果超过五个则最后一个标签栏按钮显示为更多,点击更多标签按钮会出现一个更多列表。

最后将tabbar设置为根视图控制器,分别在三个子视图控制器类中设置title和tabBarItem的显示内容。

3.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建TRTableViewController视图控制器

首先在Xcode项中创建三个带有xib的视图控制器类TRFirstViewController、TRSecondViewController,TRThirdViewController,全都继承至UIViewController,并在xib中给三个控制器的视图设置不同的背景颜色。

这三个视图控制器将作为标签控制器所管理的子控制器,如图-9所示:

图-9

步骤二:创建UITabbarController对象

在TRAppDelegate的程序入口方法中分别创建三个带有导航子视图控制器对象,代码如下所示:

 
  1. TRFirstViewController *firstVC [[TRFirstViewController alloc]initWithNibName:@"TRFirstViewController" bundle:nil];
  2. UINavigationController *navi1 [[UINavigationController alloc]initWithRootViewController:firstVC];
  3. TRSecondViewController *secondVC [[TRSecondViewController alloc]initWithNibName:@"TRSecondViewController" bundle:nil];
  4. UINavigationController *navi2 [[UINavigationController alloc]initWithRootViewController:secondVC];
  5. TRThirdViewController *thirdVC [[TRThirdViewController alloc]initWithNibName:@"TRThirdViewController" bundle:nil];
  6. UINavigationController *navi3 [[UINavigationController alloc]initWithRootViewController:thirdVC];

然后再创建一个UITabbarController对象tabbar,将三个视图控制器对象设置为tabbar的子视图控制器,屏幕下方的标签栏就回有三个按钮对应三个子视图控制,代码如下所示:

 
  1. //创建UITabBarController对象
  2. UITabBarController *tabbar [[UITabBarController alloc]init];
  3. //设置tabbar的子控制器
  4. tabbar.viewControllers = @[navi1, navi2, navi3];

最后将tabbar设置为根视图控制器,运行程序显示的第一个界面为标签控制器所管理的第一个子控制器的视图,代码如下所示:

 
  1. self.window.rootViewController = tabbar;

步骤三:设置title和tabBarItem

分别在三个子视图控制器类中的initWithNibName:bundle:初始化方法中设置title和tabBarItem的显示内容,代码如下所示:

 
  1. //TRFirstViewController类中
  2. (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
  3. {
  4. self [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  5. if (self{
  6. self.title = @"FirstVC";
  7. self.tabBarItem.image [UIImage imageNamed:@"tabbar_item_selected.png"];
  8. }
  9. return self;
  10. }
  11. //TRSecondViewController类中
  12. (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
  13. {
  14. self [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  15. if (self{
  16. self.title = @"@"SecondVC"";
  17. self.tabBarItem.image [UIImage imageNamed:@"tabbar_item_music.png"];
  18. }
  19. return self;
  20. }
  21. //TRThirdViewController类中
  22. (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
  23. {
  24. self [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  25. if (self{
  26. self.title = @"ThirdVC"";
  27. self.tabBarItem.image = [UIImage imageNamed:@"tabbar_item_store.png"];
  28. }
  29. return self;
  30. }

运行程序可见标签按钮都添加了标题和图片,如图-10所示:

图-10

3.4 完整代码

本案例中,TRAppDelegate.m文件中的完整代码如下所示:

 
  1. #import "TRAppDelegate.h"
  2. #import "TRFirstViewController.h"
  3. #import "TRSecondViewController.h"
  4. #import "TRThirdViewController.h"
  5. @implementation TRAppDelegate
  6. -(BOOL)application:(UIApplication *)application 
  7. didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  8. {
  9. self.window [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  10. self.window.backgroundColor [UIColor whiteColor];
  11. //创建tabbar所管理的子控制器,每个子控制器都带有一个导航
  12. TRFirstViewController *firstVC [[TRFirstViewController alloc]initWithNibName:@"TRFirstViewController" bundle:nil];
  13. UINavigationController *navi1 [[UINavigationController alloc]initWithRootViewController:firstVC];
  14. TRSecondViewController *secondVC [[TRSecondViewController alloc]initWithNibName:@"TRSecondViewController" bundle:nil];
  15. UINavigationController *navi2 [[UINavigationController alloc]initWithRootViewController:secondVC];
  16. TRThirdViewController *thirdVC [[TRThirdViewController alloc]initWithNibName:@"TRThirdViewController" bundle:nil];
  17. UINavigationController *navi3 [[UINavigationController alloc]initWithRootViewController:thirdVC];
  18. //创建UITabBarController对象
  19. UITabBarController *tabbar [[UITabBarController alloc]init];
  20. //设置tabbar的子控制器
  21. tabbar.viewControllers = @[navi1, navi2, navi3];
  22. //将标签控制器设置为根视图控制器,程序的第一个界面默认为标签控制器所管理的第一个子控制器的视图
  23. self.window.rootViewController = tabbar;
  24. [self.window makeKeyAndVisible];
  25. return YES;
  26. }
  27. @end
 

本案例中,TRFirstViewController.m文件中的完整代码如下所示:

 
  1. #import "TRFirstViewController.h"
  2. @implementation TRFirstViewController
  3. (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
  4. {
  5. self [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  6. if (self{
  7. self.title = @"FirstVC";
  8. self.tabBarItem.image [UIImage imageNamed:@"tabbar_item_selected.png"];
  9. }
  10. return self;
  11. }
  12. @end
 

本案例中,TRSecondViewController.m文件中的完整代码如下所示:

 
  1. #import "TRSecondViewController.h"
  2. @implementation TRFirstViewController
  3. (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
  4. {
  5. self [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  6. if (self{
  7. self.title = @"SecondVC";
  8. self.tabBarItem.image [UIImage imageNamed:@"tabbar_item_music.png"];
  9. }
  10. return self;
  11. }
  12. @end

本案例中,TRThirdViewController.m文件中的完整代码如下所示:

 
  1. #import "TRFirstViewController.h"
  2. @implementation TRFirstViewController
  3. (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
  4. {
  5. self [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  6. if (self{
  7. self.title = @"ThirdVC";
  8. self.tabBarItem.image [UIImage imageNamed:@"tabbar_item_store.png"];
  9. }
  10. return self;
  11. }
  12. @end
隐藏

4 分段选择展示

4.1 问题

IOS提供了分段选择控件,分段控件由两段或更多段构成,每一段都相当于一个独立的按钮。分段控件通常只能激活其中一个按钮。本案例将学习如何使用分段选择控件,根据不同的选择改变label的显示内容,如图-11所示:

图-11

4.2 方案

首先同样创建一个SingleViewApplication项目,然后创建一个带有xib的视图控制器类TRViewController,作为本案例的根视图控制器。

其次在xib文件中拖放一个SegmentedControl控件和一个标签控件。

然后在右边栏的第四个检查器中设置SegmentedControl控件的各属性,包括样式、每个分段按钮的显示标题、背景样色以及渲染颜色。

最后将xib中的label关联成属性,将SegmentedControl关联成方法,在TRViewController.m文件中实现SegmentedControl的事件响应方法。

4.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建TRViewController视图控制器

首先在Xcode项中创建一个带有xib的视图控制器类TRViewController,继承至UIViewController,并在TRAppDelegate的程序入口方法中创建根视图控制器对象,代码如下所示:

  1. -(BOOL)application:(UIApplication *)application 
  2. didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  3. self.window [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
  4. TRViewController *vc [[TRViewController alloc]initWithNibName:@"TRViewController" bundle:nil];
  5. self.window.rootViewController = vc;
  6. [self.window makeKeyAndVisible];
  7. return YES;
  8. }

步骤二:在xib文件中拖放控件

在xib文件中拖放一个SegmentedControl控件和一个标签控件,如图-12所示:

图-12

然后在右边栏的第四个检查器中设置日期检查器的相关属性,将分段数设置为3个,并以此设置每个分段的标题,如图-13所示:

图-13

步骤三:关联代码,实现方法

首先将xib中的label关联成私用属性label,代码如下所示:

  1. @interface TRDatePickerViewController ()
  2. @property (weak, nonatomicIBOutlet UILabel *label;
  3. @end

然后将SegmentedControl关联成事件方法segmentedControlAction:,此时SegmentedControl的事件应选择valueChanged,segmentedControlAction:方法的功能是根据不同的选择修改label的显示内容,代码如下所示:

 
  1. -(IBAction)segmentedControlAction:(UISegmentedControl *)sender {
  2. NSInteger *index [sender selectedSegmentIndex];
  3. NSString *title [sender titleForSegmentAtIndex:index];
  4. self.label.text [NSString stringWithFormat:@"用户选中%@",title];
  5. }

4.4 完整代码

本案例中,TRAppDelegate.m文件中的完整代码如下所示:

 
  1. #import "TRAppDelegate.h"
  2. #import "TRViewController.h"
  3. @implementation TRAppDelegate
  4. -(BOOL)application:(UIApplication *)application 
  5. didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  6. self.window [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
  7. TRViewController *vc [[TRViewController alloc]initWithNibName:@"TRViewController" bundle:nil];
  8. self.window.rootViewController = vc;
  9. [self.window makeKeyAndVisible];
  10. return YES;
  11. }
  12. @end
 

本案例中,TRViewController.m文件中的完整代码如下所示:

 
  1. #import "TRViewController.h"
  2. @interface TRViewController ()
  3. @property (weak, nonatomicIBOutlet UILabel *label;
  4. @end
  5. @implementation TRViewController
  6. (IBAction)segmentedControlAction:(UISegmentedControl *)sender {
  7. NSInteger *index [sender selectedSegmentIndex];
  8. NSString *title [sender titleForSegmentAtIndex:index];
  9. self.label.text [NSString stringWithFormat:@"用户选中%@",title];
  10. }
  11. @end

5 下载进度指示

5.1 问题

活动指示器UIActivityIndicatorView是UIKit框架提供的一个用于提示用户等待的指示图,是一个标准的旋转进度轮。本案例使用活动指示器和进度条模拟实现下载进度指示,如图-14所示:

图-14

5.2 方案

首先同样创建一个SingleViewApplication项目,然后创建一个带有xib的视图控制器类TRViewController,作为本案例的根视图控制器。

其次在xib文件中拖放一个ActivityIndicatorView控件和一个ProgressView控件。

然后在右边栏的第四个检查器中设置ActivityIndicatorView和ProgressView各属性。

最后将xib中的ActivityIndicatorView和ProgressView关联成私用属性,在viewDidLoad方法里面创建一个计时器,模拟下载进度。

5.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建TRViewController视图控制器

首先在Xcode项中创建一个带有xib的视图控制器类TRViewController,继承至UIViewController,并在TRAppDelegate的程序入口方法中创建根视图控制器对象,代码如下所示:

  1. -(BOOL)application:(UIApplication *)application 
  2. didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  3. self.window [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
  4. TRViewController *vc [[TRViewController alloc]initWithNibName:@"TRViewController" bundle:nil];
  5. self.window.rootViewController = vc;
  6. [self.window makeKeyAndVisible];
  7. return YES;
  8. }

步骤二:在xib文件中拖放控件

在xib文件中拖放一个ActivityIndicatorView控件和一个ProgressView控件,如图-15所示:

图-15

然后在右边栏的第四个检查器中设置ActivityIndicatorView控件的相关属性,将Hides When Stopped选项勾上,表示当ActivityIndicatorView停止旋转时隐藏,如图-16所示:

图-16

最后在右边栏的第四个检查器中设置ProgressView控件的相关属性,将Progress的值设置为0,progress是UIProgressView的一个重要属性,是float类型,默认的取值范围为0~1,如图-17所示:

图-17

步骤三:关联代码,实现方法

首先将xib中的ActivityIndicatorView和ProgressView关联成私用属性activityIndicatorView和progressView,代码如下所示:

 
  1. @interface TRDatePickerViewController ()
  2. @property (weak, nonatomicIBOutletUIActivityIndicatorView *activityIndicatorView;
  3. @property (weak, nonatomicIBOutlet UIProgressView *progressView;
  4. @end

然后在viewDidLoad方法里面创建一个NSTimer类型的计时器对象,计时器可以设定固定的时间间隔反复调用某个方法,本案例使用计时器模拟实现一个下载进度状态,每隔一定的时间修改progressView的progress值,当progress的值为1时,activityIndicatorView停止旋转并隐藏,代码如下所示:

 
  1. (void)viewDidLoad {
  2. [super viewDidLoad];
  3. //timeInterval参数是时间间隔,以秒为单位,target:参数是目标,selector参数是调用的方法,repeats参数表示是否重复调用该方法
  4. [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(download:) userInfo:nil repeats:YES];
  5. }

最后实现download:方法,该方法实现功能修改progressView的progress值,当progress的值为1时,activityIndicatorView停止旋转并隐藏,该方法传递过来的参数就是计时器对象,代码如下所示:

 
  1. //download方法的参数就是计时器对象
  2. -(void)download:(NSTimer*)timer {
  3. //活动指示器开始旋转
  4. [self.activityIndicatorView startAnimating];
  5. //每次调用进度条的progress都加0.1
  6. self.progressView.progress+=0.1;
  7. if (self.progressView.progress ==1{
  8. //当进度条的progress==1时,表示下载完成,活动指示器停止旋转
  9. [self.activityIndicatorView stopAnimating];
  10. //弹出提示对话框
  11. UIAlertView *av [[UIAlertView alloc]initWithTitle:@"提示" message:@"下载完成" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
  12. [av show];
  13. //计时器停止
  14. [timer invalidate];
  15. }
  16. }

5.4 完整代码

本案例中,TRAppDelegate.m文件中的完整代码如下所示:

 
  1. #import "TRAppDelegate.h"
  2. #import "TRViewController.h"
  3. @implementation TRAppDelegate
  4. -(BOOL)application:(UIApplication *)application 
  5. didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  6. self.window [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
  7. TRViewController *vc [[TRViewController alloc]initWithNibName:@"TRViewController" bundle:nil];
  8. self.window.rootViewController = vc;
  9. [self.window makeKeyAndVisible];
  10. return YES;
  11. }
  12. @end

本案例中,TRViewController.m文件中的完整代码如下所示:

 
  1. #import "TRViewController.h"
  2. @interface TRViewController ()
  3. @property (weak, nonatomic) IBOutlet
  4. UIActivityIndicatorView *activityIndicatorView;
  5. @property (weak, nonatomicIBOutlet UIProgressView *progressView;
  6. @end
  7. @implementation TRViewController
  8. (void)viewDidLoad {
  9. [super viewDidLoad];
  10. [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(download:) userInfo:nil repeats:YES];
  11. }
  12. //download方法的参数就是计时器对象
  13. -(void)download:(NSTimer*)timer {
  14. //活动指示器开始旋转
  15. [self.activityIndicatorView startAnimating];
  16. //每次调用进度条的progress都加0.1
  17. self.progressView.progress+=0.1;
  18. if (self.progressView.progress ==1{
  19. //当进度条的progress==1时,表示下载完成,活动指示器停止旋转
  20. [self.activityIndicatorView stopAnimating];
  21. //弹出提示对话框
  22. UIAlertView *av [[UIAlertView alloc]initWithTitle:@"提示" message:@"下载完成" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
  23. [av show];
  24. //计时器停止
  25. [timer invalidate];
  26. }
  27. }
  28. @end

6 使用DatePicker控件选择日期

6.1 问题

IOS提供了日期选择器控件,可以提供对日期的选择,本案例将学习如何使用日期选择器来选择时间,如图-18所示:

图-18

6.2 方案

首先同样创建一个SingleViewApplication项目,然后创建一个带有xib的视图控制器类TRDatePickerViewController,作为本案例的根视图控制器。

其次在xib文件中拖放一个DatePicker控件、一个标签控件以及一个按钮控件。日期选择器提供四种模式:日期、日期和时间、时间以及倒计时,本案例使用日期和时间模式。

然后在右边栏的第四个检查器中设置日期选择器的各属性,包括Mode模式、Local设定本地化、Interval设定时间间隔、Date开始时间、Constraints显示的最大和最小日期。

最后将xib中的日期选择器和label关联成属性,将日期选择器和按钮关联成方法,在TRDatePickerViewController.m文件中实现日期选择器和按钮的事件响应方法。

6.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建TRDatePickerViewController视图控制器

首先在Xcode项中创建一个带有xib的视图控制器类TRDatePickerViewController,继承至UIViewController,并在TRAppDelegate的程序入口方法中创建根视图控制器对象,代码如下所示:

 
  1. -(BOOL)application:(UIApplication *)application 
  2. didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  3. self.window [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
  4. TRDatePickerViewController *dpVC [[TRDatePickerViewController alloc]initWithNibName:@"TRDatePickerViewController" bundle:nil];
  5. UINavigationController *navi [[UINavigationController alloc]initWithRootViewController:dpVC];
  6. self.window.rootViewController = navi;
  7. [self.window makeKeyAndVisible];
  8. return YES;
  9. }

步骤二:在xib文件中拖放控件

在xib文件中拖放一个DatePicker控件、一个标签控件以及一个按钮控件,如图-19所示:

图-19

然后在右边栏的第四个检查器中设置日期检查器的相关属性,将模式选择为Date and Time,如图-20所示:

图-20

步骤三:关联代码,实现方法

首先将xib中的日期选择器和label关联成私用属性datePicker和dateLabel,代码如下所示:

 
  1. @interface TRDatePickerViewController ()
  2. @property (weak, nonatomicIBOutlet UIDatePicker *datePicker;
  3. @property (weak, nonatomicIBOutlet UILabel *dateLabel;
  4. @end

然后将日期选择器关联成事件方法datePickerValueChanged:,此时日期选择器的的事件应选择valueChanged,datePickerValueChanged:方法的功能是将日期选择器所表示的时间显示到dateLabel上,代码如下所示:

 
  1. (IBAction)datePickerValueChanged:(UIDatePicker *)sender
  2. {
  3. NSDateFormatter *df [[NSDateFormatter alloc]init];
  4. [df setDateFormat:@"YYYY-MM-dd HH:mm:ss"];
  5. self.dateLabel.text [df stringFromDate:sender.date];
  6. }

最后将按钮关联成事件方法launch:,该方法的功能是让日期选择器获取当前日期,代码如下所示:

 
  1. (IBAction)launch:(id)sender
  2. {
  3. NSDate *date = self.datePicker.date;
  4. NSDateFormatter *df [[NSDateFormatter alloc]init];
  5. [df setDateFormat:@"YYYY-MM-dd HH:mm:ss"];
  6. self.dateLabel.text [df stringFromDate:self.datePicker.date];
  7. date [NSDate date];
  8. [self.datePicker setDate:date animated:YES
  9. }

6.4 完整代码

本案例中,TRAppDelegate.m文件中的完整代码如下所示:

 
  1. #import "TRAppDelegate.h"
  2. #import "TRDatePickerViewController.h"
  3. @implementation TRAppDelegate
  4. -(BOOL)application:(UIApplication *)application 
  5. didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  6. self.window [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
  7. TRDatePickerViewController *dpVC [[TRDatePickerViewController alloc]initWithNibName:@"TRDatePickerViewController" bundle:nil];
  8. UINavigationController *navi [[UINavigationController alloc]initWithRootViewController:dpVC];
  9. self.window.rootViewController = navi;
  10. [self.window makeKeyAndVisible];
  11. return YES;
  12. }
  13. @end
 

本案例中,TRDatePickerViewController.m文件中的完整代码如下所示:

 
  1. #import "TRDatePickerViewController.h"
  2. @interface TRDatePickerViewController ()
  3. @property (weak, nonatomicIBOutlet UIDatePicker *datePicker;
  4. @property (weak, nonatomicIBOutlet UILabel *dateLabel;
  5. @end
  6. @implementation TRDatePickerViewController
  7. (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
  8. {
  9. self [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  10. if (self{
  11. self.title = @"Date";
  12. }
  13. return self;
  14. }
  15. (IBAction)launch:(id)sender
  16. {
  17. NSDate *date = self.datePicker.date;
  18. NSDateFormatter *df [[NSDateFormatter alloc]init];
  19. [df setDateFormat:@"YYYY-MM-dd HH:mm:ss"];
  20. self.dateLabel.text [df stringFromDate:self.datePicker.date];
  21. date [NSDate date];
  22. [self.datePicker setDate:date animated:YES];
  23. }
  24. (IBAction)datePickerValueChanged:(UIDatePicker *)sender
  25. {
  26. NSDateFormatter *df [[NSDateFormatter alloc]init];
  27. [df setDateFormat:@"YYYY-MM-dd HH:mm:ss"];
  28. self.dateLabel.text [df stringFromDate:sender.date];
  29. }
  30. @end
 

7 使用PickerView控件实现火车起始地点选择

7.1 问题

有时候我们还需要选择日期以外的内容,IOS提供了普通的视图选择器控件,可以满足用户的需要,本案例将学习如何使用PickerView控件实现火车起始地点选择,如图-21所示:

图-21

7.2 方案

首先同样创建一个SingleViewApplication项目,然后创建一个带有xib的视图控制器类TRPickerViewViewController,作为本案例的根视图控制器。

其次在xib文件中拖放一个PickerView控件、一个标签控件以及一个按钮控件,并在右边栏的第四个检查器中设置各个控件的相关属性。

然后将xib中的PickerView控件和label关联成属性,将按钮关联成方法。并以拉线的形式设置PickerView的委托对象为TRPickerViewViewController,TRPickerViewViewController类需要遵守协议UIPickerViewDataSource和 UIPickerViewDelegate。

最后在TRPickerViewViewController类中定义两个NSArray的属性formCity和toCity,用来存放PickerView显示的数据。

在TRPickerViewViewController类中实现按钮的事件响应方法和PickerView的协议方法,完成数据加载。

7.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建TRPickerViewViewController视图控制器

首先在Xcode项中创建一个带有xib的视图控制器类TRPickerViewViewController,继承至UIViewController,并在TRAppDelegate的程序入口方法中创建根视图控制器对象,代码如下所示:

  1. -(BOOL)application:(UIApplication *)application 
  2. didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  3. self.window [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
  4. TRPickerViewViewController *pvVC [[TRPickerViewViewController alloc]initWithNibName:@"TRPickerViewViewController" bundle:nil];
  5. UINavigationController *navi [[UINavigationController alloc]initWithRootViewController:pvVC]; self.window.rootViewController = navi;
  6. [self.window makeKeyAndVisible];
  7. return YES;
  8. }

步骤二:在xib文件中拖放控件

在xib文件中拖放一个PickerView控件、一个标签控件以及一个按钮控件,并在右边栏的第四个检查器中设置各个控件的相关属性,如图-22所示:

图-22

然后将xib中的PickerView控件和label关联成私有属性pickerView和label,将按钮关联成方法luanch:,代码如下所示:

  1. @interface TRPickerViewViewController ()
  2. @property (weak, nonatomicIBOutlet UIPickerView *pickerView;
  3. @property (weak, nonatomicIBOutlet UILabel *label;
  4. @end

最后以拉线的形式设置PickerView的dataSource和delegate两个委托对象为File‘s Owner,即TRPickerViewViewController,如图-23所示:

图-23

步骤三:遵守协议,实现方法

在TRPickerViewViewController类中定义两个NSArray类型的公开属性formCity和toCity,用来存放PickerView显示的数据,并重写setter方法初始化数据,代码如下所示:

  1. @interface TRPickerViewViewController : UIViewController
  2. @property (nonatomic, strong)NSArray *fromCitys;
  3. @property (nonatomic, strong)NSArray *toCitys;
  4. @end
  5. //重写setter方法,初始化数据
  6. (NSArray *)fromCitys
  7. {
  8. if(!_fromCitys)_fromCitys = @[@"北京",@"上海",@"广州",@"深圳",@"成都"];
  9. return _fromCitys;
  10. }
  11. (NSArray *)toCitys
  12. {
  13. if(!_toCitys)_toCitys = @[@"上海",@"广州",@"深圳",@"成都", @"杭州"];
  14. return _toCitys;
  15. }

然后TRPickerViewViewController类需要遵守协议UIPickerViewDataSource和 UIPickerViewDelegate,并且实现相关的协议方法,完成数据加载,代码如下所示:

  1. //遵守协议
  2. @interface TRPickerViewViewController () <UIPickerViewDataSource, UIPickerViewDelegate>
  3. //告诉pickerView显示多少组
  4. (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
  5. {
  6. return 2;
  7. }
  8. //告诉pickerView每组显示多少行
  9. -(NSInteger)pickerView:(UIPickerView *)pickerView 
  10. numberOfRowsInComponent:(NSInteger)component
  11. {
  12. if (component==0{
  13. return self.fromCitys.count;
  14. }else if(component==1){
  15. return self.toCitys.count;
  16. }
  17. return 0;
  18. }
  19. //告诉pickerView每行显示的标题
  20. -(NSString *)pickerView:(UIPickerView *)pickerView 
  21. titleForRow:(NSInteger)row 
  22. forComponent:(NSInteger)component
  23. {
  24. if(component==0){
  25. return self.fromCitys[row];
  26. }else{
  27. return self.toCitys[row];
  28. }
  29. }

最后在TRPickerViewViewController类中实现按钮的事件响应方法luanch:,当点击按钮时label上显示用户选择的起始地点信息,代码如下所示:

  1. (IBAction)luanch:(id)sender
  2. {
  3. NSInteger fromIndex [self.pickerView selectedRowInComponent:0];
  4. NSInteger toIndex [self.pickerView selectedRowInComponent:1];
  5. self.label.text [NSString stringWithFormat:@"用户想从%@到%@", self.fromCitys[fromIndex], self.toCitys[toIndex]];
  6. }

7.4 完整代码

本案例中,TRAppDelegate.m文件中的完整代码如下所示:

 
  1. #import "TRAppDelegate.h"
  2. #import "TRDatePickerViewController.h"
  3. @implementation TRAppDelegate
  4. -(BOOL)application:(UIApplication *)application 
  5. didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  6. self.window [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
  7. TRPickerViewViewController *pvVC [[TRPickerViewViewController alloc]initWithNibName:@"TRPickerViewViewController" bundle:nil];
  8. UINavigationController *navi [[UINavigationController alloc]initWithRootViewController:pvVC];
  9. self.window.rootViewController = navi;
  10. [self.window makeKeyAndVisible];
  11. return YES;
  12. }
  13. @end

本案例中,TRPickerViewViewController.h文件中的完整代码如下所示:

 
  1. #import<UIKit/UIKit.h>
  2. @interface TRPickerViewViewController : UIViewController
  3. @property (nonatomic, strong)NSArray *fromCitys;
  4. @property (nonatomic, strong)NSArray *toCitys;
  5. @end
 

本案例中,TRPickerViewViewController.m文件中的完整代码如下所示:

 
  1. #import "TRPickerViewViewController.h"
  2. @interface TRPickerViewViewController () <UIPickerViewDataSource, UIPickerViewDelegate>
  3. @property (weak, nonatomicIBOutlet UIPickerView *pickerView;
  4. @property (weak, nonatomicIBOutlet UILabel *label;
  5. @end
  6. @implementation TRPickerViewViewController
  7. (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
  8. {
  9. self [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  10. if (self{
  11. self.title = @"起始地点";
  12. }
  13. return self;
  14. }
  15. (NSArray *)fromCitys
  16. {
  17. if(!_fromCitys)_fromCitys = @[@"北京",@"上海",@"广州",@"深圳",@"成都"];
  18. return _fromCitys;
  19. }
  20. (NSArray *)toCitys
  21. {
  22. if(!_toCitys)_toCitys = @[@"上海",@"广州",@"深圳",@"成都", @"杭州"];
  23. return _toCitys;
  24. }
  25. //告诉pickerView显示多少组
  26. (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
  27. {
  28. return 2;
  29. }
  30. //告诉pickerView每组显示多少行
  31. (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
  32. {
  33. if (component==0{
  34. return self.fromCitys.count;
  35. }else if(component==1){
  36. return self.toCitys.count;
  37. }
  38. return 0;
  39. }
  40. //告诉pickerView每行显示的标题
  41. (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
  42. {
  43. if(component==0){
  44. return self.fromCitys[row];
  45. }else{
  46. return self.toCitys[row];
  47. }
  48. }
  49. (IBAction)luanch:(id)sender
  50. {
  51. NSInteger fromIndex [self.pickerView selectedRowInComponent:0];
  52. NSInteger toIndex [self.pickerView selectedRowInComponent:1];
  53. self.label.text [NSString stringWithFormat:@"用户想从%@到%@", self.fromCitys[fromIndex], self.toCitys[toIndex]];
  54. }
  55. @end
 

8 网页浏览

8.1 问题

网页控件UIWebView是UIKit框架提供的用于访问网页的视图控件,它有一个内置的浏览器。本案例将学习如何使用UIWebView控件实现一个简易的浏览器,并且具有网页的前进、后退和刷新功能,如图-24所示:

图-24

8.2 方案

首先同样创建一个SingleViewApplication项目,然后创建一个带有xib的视图控制器类TRViewController,作为本案例的根视图控制器。

其次在xib文件中拖放一个UIWebView控件用于加载网页、一个ActivityIndicatorView控件用于加载等待、一个TextField控件用于用户输入网址以及三个Button控件用于控制前进、后退和刷新。

然后在右边栏的第四个检查器中设置各控件的相关属性。

最后将xib中的UIWebView控件、ActivityIndicatorView控件和TextField关联成私有属性。

再分别将三个Button控件和TextField控件关联成方法,在TRViewController.m文件中实现TextField控件和按钮事件的响应方法。

8.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建TRViewController视图控制器

首先在Xcode项中创建一个带有xib的视图控制器类TRViewController,继承至UIViewController,并在TRAppDelegate的程序入口方法中创建根视图控制器对象,代码如下所示:

 
  1. -(BOOL)application:(UIApplication *)application 
  2. didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  3. self.window [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
  4. TRViewController *vc [[TRViewController alloc]initWithNibName:@"TRViewController" bundle:nil];
  5. self.window.rootViewController = vc;
  6. [self.window makeKeyAndVisible];
  7. return YES;
  8. }

步骤二:在xib文件中拖放控件

在xib文件中拖放一个UIWebView控件、一个ActivityIndicatorView控件、一个TextField控件以及三个Button控件,如图-25所示:

图-25

然后在右边栏的第四个检查器中设置个控件的相关属性,将WebView控件的Scales Page To Fit选项勾上,表示会根据WebView的大小显示所访问的网页,如图-26所示:

图-26

步骤三:关联代码,实现方法

首先将xib中UIWebView控件、ActivityIndicatorView控件和TextField关联成私有属性webView、tf和activityIndicatorView,代码如下所示:

 
  1. @interface TRDatePickerViewController ()
  2. @property (weak, nonatomicIBOutlet UIWebView *webView;
  3. @property (weak, nonatomicIBOutlet UITextField *tf;
  4. @property (weak, nonatomicIBOutlet UIActivityIndicatorView *activityIndicatorView;
  5. @end

其次将TextField控件的Did End On Exit事件关联方法go:,当点击键盘右下角的按钮时就访问所输入的网址,代码如下所示:

 
  1. (IBAction)go:(UITextField *)sender
  2. {
  3. //tf退出第一响应
  4. [sender resignFirstResponder];
  5. //创建一个url请求
  6. NSString *urlString [NSString stringWithFormat:@"http://%@",sender.text];
  7. sender.text = urlString;
  8. NSURL *url [NSURL URLWithString:urlString];
  9. NSURLRequest *request [NSURLRequest requestWithURL:url];
  10. //webView发送请求
  11. [self.webView loadRequest:request];
  12. }

然后分别将三个按钮关联成事件方法goBack:、goForward以及reload:,三个方法分别实现网页的后退、前进和刷新,代码如下所示:

 
  1. (IBAction)goBack:(UIButton *)sender {
  2. [self.webView goBack];
  3. }
  4. (IBAction)gouForward:(UIButton *)sender {
  5. [self.webView goForward];
  6. }
  7. (IBAction)reLoad:(UIButton *)sender {
  8. [self.webView reload];
  9. }

最后根据webView的属性loading的值,控制activityIndicatorView的旋转和显示,代码如下所示:

 
  1. -(void)viewDidLoad {
  2. [super viewDidLoad];
  3. [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(isActivity) userInfo:nil repeats:YES];
  4. }
  5. -(void)isActivity {
  6. if (self.webView.isLoading==YES{
  7. //当网页正在加载时,活动指示器开始旋转
  8. [self.activityIndicatorView startAnimating];
  9. }else {
  10. //当网页加载完成,活动指示器停止旋转
  11. [self.activityIndicatorView stopAnimating];
  12. }
  13. }

8.4 完整代码

本案例中,TRAppDelegate.m文件中的完整代码如下所示:

 
  1. #import "TRAppDelegate.h"
  2. #import "TRViewController.h"
  3. @implementation TRAppDelegate
  4. -(BOOL)application:(UIApplication *)application 
  5. didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  6. self.window [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
  7. TRViewController *vc [[TRViewController alloc]initWithNibName:@"TRViewController" bundle:nil];
  8. self.window.rootViewController = vc;
  9. [self.window makeKeyAndVisible];
  10. return YES;
  11. }
  12. @end
 

本案例中,TRViewController.m文件中的完整代码如下所示:

 
  1. #import "TRViewController.h"
  2. @interface TRViewController ()
  3. @property (weak, nonatomicIBOutlet UIWebView *webView;
  4. @property (weak, nonatomicIBOutlet UITextField *tf;
  5. @property (weak, nonatomicIBOutlet UIActivityIndicatorView *activityIndicatorView;
  6. @end
  7. @implementation TRViewController
  8. -(void)viewDidLoad {
  9. [super viewDidLoad];
  10. [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(isActivity) userInfo:nil repeats:YES];
  11. }
  12. -(void)isActivity {
  13. if (self.webView.isLoading==YES{
  14. [self.activityIndicatorView startAnimating];
  15. }else {
  16. [self.activityIndicatorView stopAnimating];
  17. }
  18. }
  19. (IBAction)go:(UITextField *)sender
  20. {
  21. [sender resignFirstResponder];
  22. NSString *urlString [NSString stringWithFormat:@"http://%@",sender.text];
  23. sender.text = urlString;
  24. NSURL *url [NSURL URLWithString:urlString];
  25. NSURLRequest *request [NSURLRequest requestWithURL:url];
  26. [self.webView loadRequest:request];
  27. }
  28. (IBAction)goBack:(UIButton *)sender {
  29. [self.webView goBack];
  30. }
  31. (IBAction)gouForward:(UIButton *)sender {
  32. [self.webView goForward];
  33. }
  34. (IBAction)reLoad:(UIButton *)sender {
  35. [self.webView reload];
  36. }
  37. @end

转载于:https://www.cnblogs.com/hytx/p/5049504.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/357868.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【APICloud系列|24】 MNNavigationMenu模块(导航菜单)的实现

导读:MNNavigationMenu 是一个导航栏菜单,开发者可自定义其中的样式和按钮个数,超出屏幕部分可左右拖动查看。 模块详情:http://www.apicloud.com/mod_detail/12417 index.html <!doctype html> <html> <head><meta charset="utf-8">&…

mysql2教程_mySQL 教程 第2章 安装和介绍mySQL

设置mySQL字符集支持中文的字符集是utf8&#xff0c;该设置可以更改mySQL配置文件进行全局设置&#xff0c;也可以针对数据库设置&#xff0c;也可以针对表设置&#xff0c;也可以针对列设置。字符集更改后新插入的数据生效&#xff0c;对以前不生效。练习1&#xff1a;更改MyS…

java 更新订单状态_Java 8状态更新

java 更新订单状态即将到来的Java SE 8发行版的两大新语言功能是Lambda Expressions和Modularity。 这两天的状态更新都已经发布。 我会与您分享链接&#xff0c;因此您可能会在假期中通读它们 Oracle计划在2013年中期发布Java SE 8。 Lambda项目 Lambda项目以及JSR-335希望提…

基于JBoss Fuse 6.2的JBoss BPM微服务集成指南

今年年初&#xff0c;我们宣布了JBoss BPM Suite令人兴奋的示例项目&#xff0c;该项目围绕一个正在运行的在线Travel Agency项目展开。 最初是利用Web服务&#xff0c;后来我们在JBoss Fuse的帮助下迁移到微服务 。 随着JBoss Fuse 6.2的发布&#xff0c;我们希望重新访问该…

mysql zip 还原_mysql 压缩还原数据库

MySQL数据库备份和还原的常用命令其实很多情况下mysql备份就是采用了这些命令&#xff0c;例如&#xff1a;mysql导入和导出数据linux自动定时备份web程序和mysql数据库备份MySQL数据库的命令mysqldump -hhostname -uusername -ppassword databasename > backup...文章无声胜…

jvm调试工具_调试JVM

jvm调试工具在某些&#xff08;极少数&#xff09;情况下&#xff0c;您可能会遇到使JVM本身崩溃的情况。 我最近通过将ThreadGroup的名称设置为null来进行管理 。 在这些情况下&#xff0c;调试JVM本身很有用&#xff0c;这样可以更精确地定位崩溃。 这是执行此操作的步骤&…

遮罩窗体弹出登录页面代码实现

先上效果图(本人喜欢胡巴&#xff0c;背景用了胡巴)&#xff0c;鼠标滑过页面&#xff0c;图片变暗&#xff0c;透明度为0.4&#xff0c;同时弹出登录窗口。 接下来先看css代码(写的可能不是很规范&#xff0c;根据调整样式顺序写的) body{background-color: black;width: 100%…

【APICloud系列|27】 UICalendar模块(日历)的实现

导读:UICalendar 是一个日历选择模块;可自定义日历的样式,添加特殊日期标注,切换月份,设置指定日期;用于实现常用的日期选择,日历展示功能 模块地址 UICalendar 是一个日历选择模块;可自定义日历的样式,添加特殊日期标注,切换月份,设置指定日期;用于实现常用的日期…

使用Camel从WildFly 8向WebLogic 12发送JMS消息

系统集成是一个很好的挑战。 特别是当您在寻找通信标准和可靠的解决方案时。 在当今的微服务世界中&#xff0c;每个人都在谈论REST服务和基于http的协议。 实际上&#xff0c;对于大多数企业项目来说&#xff0c;这往往是远远不够的&#xff0c;而这些项目通常具有更复杂的要求…

【APICloud系列|28】 UIChatBox 模块(聊天输入框)的实现

导读:UIChatBox 模块是一个聊天输入框模块,开发者可自定义该输入框的功能 项目结构: config.xml <?xml version="1.0" encoding="UTF-8"?><widget id="A6909001303255" version="0.0.1"> <name>UIChatbox<…

mysql索引参数_MySQL索引介绍

索引由数据库表中一列或者多列组合而成&#xff0c;其作用是提高对表中数据的查询速度。创建索引是指在某个表的一列或者多列上建立一个索引&#xff0c;用来提高对表的访问速度&#xff0c;创建索引由三种方法&#xff1a;在创建表的时候创建&#xff0c;在已存在的表上创建和…

【APICloud系列|31】百度导航功能的实现

导读:百度导航基础功能。d用到了bMap模块,baiduNavigation模块,UIListView模块。样式完全来自AUI。js用到了zepto.j 效果图: 项目结构: index.html <!doctype html> <html> <head><meta charset="utf-8"><meta name="viewport…

osgi简介_OSGi:简介

osgi简介为基于Java的系统创建的OSGi提供了模块化系统的框架。 OSGi使得可以定义每个单独模块与其他模块的依赖关系&#xff0c;并使用户能够控制生命周期并动态更改系统的每个组件。 OSGi是一个规范&#xff0c;最常见的实现可以算作Equinox &#xff0c; Apache Felix和Knopl…

GC基本算法及C++GC机制

前言 垃圾收集器是一种动态存储分配器&#xff0c;它自动释放程序不再需要的已分配的块&#xff0c;这些块也称为垃圾。在程序员看来&#xff0c;垃圾就是不再被引用的对象。自动回收垃圾的过程则称为垃圾收集&#xff08;garbage collection&#xff09;。在一个支持垃圾收集的…

【APICloud系列|32】 aMapNavigation高德地图导航的实现

导读:aMapNavigation 模块封装了高德导航的sdk,支持语音导航功能。用户可自行算路策略类型。开发者只需输入起点终点经纬度即可轻松集成高德导航功能,本模块是由第三方模块开发者提供,使用本模块需在线云编译安装包。 效果图: 项目结构: index.html <!doctype html&…

JDK 9早期版本安装后的Windows注册表清理

在我的上一篇博文中 &#xff0c;我演示了在安装早期版本的JDK 9&#xff08;内部版本68&#xff09;之后围绕Oracle Java符号链接 &#xff08;基于Windows的计算机上的C:\ProgramData\Oracle\Java\javapath\目录&#xff09;的问题的解决方案。这似乎阻止了早期&#xff08;更…

java实现网上招标系统

导读:本设计尝试用JSP在网络上架构一个下沙派威客网,以推进网站无纸化,过程电子化,管理智能化的发展。本文从理论和实践两个角度出发,对一个具有数据分析功能的下沙派威客网进行设计与实现分析。论文首先较为详尽地介绍了面向对象分析与设计的有关概念与技术,特别深入介绍…

java实现俄罗斯方块项目

导读:俄罗斯方块项目,基本功能包括:游戏主界面显示模块、方块及数据显示模块、方块移动控制模块、游戏界面颜色控制模块、游戏进度、等级控制模块等。本项目结构如下: (1)游戏主界面显示模块: 显示游戏和帮助两个菜单; 游戏使用功能键盘,得分 等级; (2)画布…

js数组操作大全

shift:删除原数组第一项&#xff0c;并返回删除元素的值&#xff1b;如果数组为空则返回undefined Javascript代码 var a [1,2,3,4,5]; var b a.shift(); //a:[2,3,4,5] b:1 unshift:将参数添加到原数组开头&#xff0c;并返回数组的长度 Javascript代码 var a [1,2,…

mysql与mssql中datetime类型字段问题_excel数据存入sqlserver过程中,遇到Datetime的格式问题。...

先讲一下我实现的大致思路&#xff1a; 1 读取excel数据&#xff0c;赋值到datatable中&#xff0c;然后在页面上显示 细节描述&#xff1a;有一些列是存到数据库时要是datetime格式的&#xff0c;我在赋值到datatable时也是做 如下处理的 DataColumn dtColumn new DataColumn…