使用视图控制器(View Controllers)
本文的学习目标
- 理解视图控制器的生命周期及其何时回调方法,如viewDidLoad、viewWillAppear和viewDidAppear
- 在各视图控制器之间传递数据
- 关闭一个视图控制器
- 使用手势识别作为产生事件的一个附加层级
- 基于视图和控件(UIView/UIControl)类的继承关系预期对象的行为
- 使用资产目录(asset catalog)添加图像资产到项目中
理解视图控制器的生命周期
目前FoodTracker项目有一个单一页面Scene,其界面由一个单一视图控制器管理。当如果创建更复杂的应用时,会处理更多的页面,当视图移动到屏前和屏后时管理这些视图的加载和卸载。
UIViewController类(和其子类)的对象拥有一组管理视图继承关系的方法,当一个视图控制器在不同状态之间切换时,iOS在合适的时机自动调用这些方法。当创建一个视图控制器的子类(subclass)时,子类继承了父类(UIViewController)的方法,允许在每个方法中加入定制的行为。
UIViewController类的方法如下:
- viewDidLoad(),当视图控制器的内容视图(content view,位于视图层级的最顶层)被创建和从storyboard加载时,本方法会被调用,用于建立初始的设置。
- viewWillAppear(),用于当视图变为可见之前的任何用户操作由于视图的可见性可以被其他视图显现或遮挡,本方法总会在内容视图显示在前屏之前立即被调用。
- viewDidAppear(),用于一旦视图可见的任何用户操作,如取回数据或者显示一个动画。由于视图的可见性可以被其他视图显现或遮挡,本方法总会在内容视图显示在前屏后立即被调用。
增加一个菜品照片
增加一个图像视图(image view)到页面中
- 打开主storyboard界面资源文件;
- 在对象库中检索image view;
- 找到图像视图将其拖拽到页面中,放置在堆栈视图(stack view)中按钮的下面;
- 在图像视图选中状态,设置尺寸如图;
- 设置Intrinsic Size字段为Placeholder,设置宽度Width和高度Height为320;
- 点击画布(canvas)右下方Pin菜单按钮;
- 添加1:1外观比例(aspect ratio)比例约束;
- 选中图像视图时,打开属性编辑器,在Interaction字段设置允许用户交互(User Interaction Enable),这样图像视图可以接收手势事件。
显示缺省照片
当用户可以与图像视图交互来选择一个照片时需要得到指示,增加一个缺省的占位图像通知用户可以选择一个照片。
增加一个图像到项目中
- 在项目导航栏找到Assets.xcassets,查看资产目录(asset catalog);
- 点击左下角的“+”按钮,选择“New Image Set”;
- 双击图像集合名,改名为defaultPhoto;
- 在电脑中找到想要添加的图像;
- 将图像拖拽到图像集合的2x(对应于iPhone6模拟器的显示分辨率)空位处。
在图像视图中显示一个缺省的图像
- 打开storyboard界面文件,选中图像视图控件;
- 打开属性编辑器,在标注“Image”的字段选择defaultPhoto为缺省图像。
连接图像视图控件到代码中
现在需要实现必要的功能,在运行时改变图像视图的图像。首先需要连接图像视图到代码中。
连接图像视图到ViewController.swift文件的代码中
- 点击Xcode工具条上的助手按钮,打开助手编辑器;
- 在storyboard上选中图像视图;
- 在按下Control键同时拖拽图像视图到代码编辑区;
- 在提示对话框中,Name填写为photoImageView;
- 点击“Connect”按钮。
Xcode增加以下代码:@IBOutlet weak var photoImageView: UIImageView!
创建手势识别器
图像视图不是控件(cotrol)不能设计成控件响应于输入例如一个按钮的方式。因此不能简单创建一个动作方法,当用户点击一个图像视图来触发这个动作方法。不过可以通过给图像视图增加一个手势识别器的方式实现同样功能。图像识别器(gesture recognizers)是绑定到一个视图上的对象,允许视图像一个控件一样响应于动作事件,图像识别器分辨触碰行为,决定是否对应于特定的手势,例如:一个滑动、缩放、或旋转等。
绑定一个点击手势识别器(UITapGestureRecognizer)到图像视图,识别用户点击图像视图的手势。
增加一个点击手势识别器到图像视图
- 打开对象库(Object Library),检索“tap gesture”;
- 找到“Tap Gesture Recognizer”对象,拖拽其到页面中的图像视图上。
连接手势识别器对象到代码中
连接手势识别器到ViewController.swift文件代码中
- 按住Control键拖拽手势识别器到代码编辑区中;
- 在提示对话框中选择Connection方式为“Action”;
- 在Name字段输入selectImageFromPhotoLibrary;
- 在type字段选择“UITapGestureRecognizer”;
- 点击“Connect”按钮。
Xcode增加代码如下。@IBAction func selectImageFromPhotoLibrary(sender: UITapGestureRecognizer) { }
创建图像拣取器(Image Picker)用于响应用户的点击
用户点击图像视图,能够从一组照片中选择一个照片。UIImagePickerController类内建了相关的各种行为,管理一个界面用于拍照和选择保存的图像,需要使用图像拣取器代理来使用图像拣取控制器,该代理的协议名为“UIImagePickerControllerDelegate”。
ViewController类要遵从UIImagePickerControllerDelegate协议,同时还要遵从UINavigationControllerDelegate协议(实现一些导航视图切换)
遵从UIImagePickerControllerDelegate和UINavigationControllerDelegate协议
-
在项目导航栏选择ViewController.swift文件
-
找到ViewController类定义行
class ViewController: UIViewController, UITextFieldDelegate {
-
使用”,”添加UIImagePickerControllerDelegate和UINavigationControllerDelegate
class ViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
实现selectImageFromPhotoLibrary(_:)动作方法
-
在ViewController.swift代码中找到selectImageFromPhotoLibrary动作方法
-
添加如下代码
@IBAction func selectImageFromPhotoLibrary(sender: UITapGestureRecognizer) { nameTextField.resignFirstResponder() }
-
在selectImageFromPhotoLibrary方法添加创建视图拾取控制器;
let imagePickerController = UIImagePickerController()
-
添加下面代码;
imagePickerController.sourceType = .PhotoLibrary
设置视图拾取控制器(image picker controller)的图像来源,.PhotoLibrary选项是使用模拟器的相机胶卷。
-
设置视图拾取控制器的代理为ViewController;
imagePickerController.delegate = self
-
添加下面代码。
presentViewController(imagePickerController, animated: true, completion: nil)
presentViewController(_:animated:completion:)方法用于模式显示一个视图控制器,这里是视图拾取控制器。
完整的selectImageFromPhotoLibrary方法代码如下:
@IBAction func selectImageFromPhotoLibrary(sender: UITapGestureRecognizer) { nameTextField.resignFirstResponder() let imagePickerController = UIImagePickerController() imagePickerController.sourceType = .PhotoLibrary imagePickerController.delegate = self presentViewController(imagePickerController, animated: true, completion: nil) }
为了给予用户选取图片的能力,需要视图拾取控制器代理协议定义的两个方法:
func imagePickerControllerDidCancel(picker: UIImagePickerController) func imagePickerController(picker: UIImagePickerController,didFinishPickingMediaWithInfo info: [String : AnyObject])
实现imagePickerControllerDidCancel(_:)方法
- 在ViewController.swift中//MARK: Actions代码段添加代理的//MARK注释
// MARK: UIImagePickerControllerDelegate
- 在上面注释下添加方法和代码。
func imagePickerControllerDidCancel(picker: UIImagePickerController) { dismissViewControllerAnimated(true, completion: nil) }
实现imagePickerController(_:didFinishPickingMediaWithInfo:)方法
- 在imagePickerControllerDidCancel方法后面添加方法;
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) { }
-
添加图像获取的代码;
let selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage
-
添加给图像视图设置图像的代码;
photoImageView.image = selectedImage
-
添加关闭视图拾取控制器的代码。
dismissViewControllerAnimated(true, completion: nil)
完整代码如下:
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) { let selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage photoImageView.image = selectedImage dismissViewControllerAnimated(true, completion: nil) }
运行模拟器,提示用户要授予FoodTracker应用访问照片库的权限。
增加图像到模拟器
- 运行模拟器;
- 在电脑中,选中要添加的图像;
- 拖拽图像到模拟器中。
网友评论