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, nonatomic) IBOutlet 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, nonatomic) IBOutlet 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(150, 150);
  5. //设置每个cell之间的间距
  6. layout.minimumInteritemSpacing = 10;
  7. //设置每个分局的边距
  8. layout.sectionInset = UIEdgeInsetsMake(150, 20, 150, 20);
  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(0, 0, 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(150, 150);
  14. //设置每个cell之间的间距
  15. layout.minimumInteritemSpacing = 10;
  16. //设置每个分局的边距
  17. layout.sectionInset = UIEdgeInsetsMake(150, 20, 150, 20);
  18. //设置滚动方向为水平方向
  19. layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
  20. //创建集合视图对象
  21. CGSize screenSize = [[UIScreen mainScreen] bounds].size;
  22. UICollectionView *collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 0, 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, nonatomic) IBOutlet 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, nonatomic) IBOutlet 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, nonatomic) IBOutletUIActivityIndicatorView *activityIndicatorView;
  3. @property (weak, nonatomic) IBOutlet 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, nonatomic) IBOutlet 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, nonatomic) IBOutlet UIDatePicker *datePicker;
  3. @property (weak, nonatomic) IBOutlet 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, nonatomic) IBOutlet UIDatePicker *datePicker;
  4. @property (weak, nonatomic) IBOutlet 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, nonatomic) IBOutlet UIPickerView *pickerView;
  3. @property (weak, nonatomic) IBOutlet 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, nonatomic) IBOutlet UIPickerView *pickerView;
  4. @property (weak, nonatomic) IBOutlet 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, nonatomic) IBOutlet UIWebView *webView;
  3. @property (weak, nonatomic) IBOutlet UITextField *tf;
  4. @property (weak, nonatomic) IBOutlet 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, nonatomic) IBOutlet UIWebView *webView;
  4. @property (weak, nonatomic) IBOutlet UITextField *tf;
  5. @property (weak, nonatomic) IBOutlet 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

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

  1. iOS--UI之导航控制器与标签控制器

    1.导航控制器和标签控制器都属于容器控制器: a)容器控制器本身不负责向用户展示有意义的内容,只是负责管理子控制器,管理控制器的展示和子视图控制器视图之间的切换 b)容器类控制器本身也是视图控制器,都 ...

  2. Android高级控件----AdapterView与Adapter详解

    在J2EE中提供过一种非常好的框架--MVC框架,实现原理:数据模型M(Model)存放数据,利用控制器C(Controller)将数据显示在视图V(View)上.在Android中有这样一种高级控件 ...

  3. 2022 最新 Android 基础教程,从开发入门到项目实战【b站动脑学院】学习笔记——第八章:高级控件

    本章介绍了App开发常用的一些高级控件用法,主要包括:如何使用下拉框及其适配器.如何使用列表 类视图及其适配器.如何使用翻页类视图及其适配器.如何使用碎片及其适配器等.然后结合本章所学 的知识,演示了 ...

  4. 十四、windows窗体高级控件

    1 PictureBox控件 PictureBox控件可以显示来自位图.图标或者原文件,以及来自增强的元文件.Jpeg或GIF文件的图形.如果控件不足以显示整幅图像,则捡钱图像以适应控件的大小 usi ...

  5. Android从入门到进阶之高级控件

    高级控件 1.自动完成文本控件 在搜索引擎(百度.搜狗)输入几个文字,会出来一些提示.可以减少用户的输入,提高程序的效率.刚才看到的自动提示,ajax技术. 1.1AotoCompleteTextVi ...

  6. 三、PyQt5高级控件的使用

    (四)PyQt5高级控件的使用 PyQt5中包含了很多用于简化窗口设计的可视化控件,除了常用控件外,还有一些关于进度.展示数据等的高级控件. 本章重点讲解PyQt5程序开发中用到的一些高级控件,主要包 ...

  7. 《移动项目实践》实验报告——Android高级控件

    实验目的 1.熟悉App开发常用的一些高级控件及相关工具,主要包括日期时间控件的用法.列表类视图及其适配器的用法.翻页类视图及其适配器的用法.碎片及其适配器的用法等: 2.熟悉四大组件之一广播Broa ...

  8. Android高级控件(一)——ListView绑定CheckBox实现全选,增加和删除等功能

    Android高级控件(一)--ListView绑定CheckBox实现全选,增加和删除等功能 这个控件还是挺复杂的,也是项目中应该算是比较常用的了,所以写了一个小Demo来讲讲,主要是自定义adap ...

  9. 移动开发技术(Android)——实验5 Android高级控件的应用

    移动开发技术--实验5 Android高级控件的应用 一.实验目的 二.实验内容 1.Spinner.ListView控件与Adapter适配器(一) 2.Spinner.ListView控件与Ada ...

最新文章

  1. 二十六、事务的隔离级别
  2. Spring boot的@Value注解
  3. 云炬金融每日一题20211008
  4. 一个菜鸟从高一到大二的作品整理
  5. 不会提示是否关闭浏览器 IE6、IE7、FF通用代码
  6. TCP多进程并发服务端 Linux socket编程入门(2)
  7. php 正则替换 ubb,php实现过滤UBB代码的类
  8. Touch 方法属性 映射工具
  9. java的基本循环结构_Java基础之(九):循环结构
  10. 问题十五:C++中抽象类,虚函数是什么鬼?怎么测试
  11. “智慧城市”建设为何需要“顶层设计”
  12. 百度应用市场app认领操作
  13. import cv2
  14. Java 简易五子棋
  15. Spec2006使用说明
  16. 【图】爱情公寓里你最喜欢谁?爱情公寓3的投票,快来参加哦。
  17. echarts饼图制作
  18. Project计算项目进度
  19. 01年北漂程序员年度总结,2021我废了,2022我重新做人了
  20. JAVA毕业设计Web端校园报修系统计算机源码+lw文档+系统+调试部署+数据库

热门文章

  1. pc端游戏修改器_原神:不要吐槽手机内存了,想要获得最佳游戏体验,PC端最合适...
  2. 【技术解决方案】Windows平台下摄像头采集方案
  3. charles代理手机调试_H5开发 移动端 调试之 Charles 抓包 和 Map Remote
  4. mysql降低数据库版本_三步10分钟搞定数据库版本的降迁 (将后台数据库SQL2008R2降为SQ...
  5. iphone已停用怎么解锁_两种无密码解锁iPhone锁屏密码的方法
  6. 边沿触发是什么意思_集基耦合双稳电路,集成化单稳电路,数字逻辑电路,门电路,触发器...
  7. 哪些原因会导致rs485转换器信号受干扰?
  8. 六种让路由器与交换机更加安全的方法
  9. [渝粤教育] 中国人民解放军陆军工程大学 机械基础 参考 资料
  10. 【渝粤题库】陕西师范大学200131中国古代文论 作业(专升本)