第 5 章介绍了 UITabBarController 对象,通过使用该对象,用户可以切换不同的屏幕 。 当要切换的各个屏幕之间没有相互依赖关系时,该对象可以很好地完成任务 。 但是,当多个屏幕互有关联
时,就要使用另一种视图控制器 。
打开 Main. storyboard , 然后选择 ItemsViewController 。在 Editor (编辑)菜单中选择 Embed In(嵌入) ->Navigation Controller 。这将会把 ItemsViewController 设置为 UINavigationController 的根视图控制器。同时 storyboard 会把 UINavigationController 设置为初始视图控制器 。
编译并运行应用,然后 ……应用就崩溃了。是什么原因 呢 ?之前在 AppDelegate 中 ,代 码将 rootViewCont roller 声明为 ItemsViewController 类型 。
- let itemsController = window!. rootViewController as! ItemsViewController
- 现在已经把 ItemsViewController 嵌套在 UINavigationController 中了,因此需要更新这里的代码 。打开SceneDeleDelegate,更新application(_:didfinishlaunchingWithOptions:) 方法:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
let itemStore = ItemStore() //方法实例化
// let itemsController = window!.rootViewController as! ItemsViewController
let navController = window!.rootViewController as! UINavigationController
let itemsController = navController.topViewController as! ItemsViewController
itemsController.itemStore = itemStore //将其 ItemStore 属性设置为 ItemStore 的新实例。
}
隐藏键盘
点击之后出现键盘是 UITextField 和 UITextView 自带的行为,因此不需要做任何额外工作,键盘就会出现。但是有时候需要确保键盘的行为和预期是一致的。
现在键盘遮挡问题还不是很明显,如果在屏幕上再加入一些 Item 的信息,用户就需要一 种收起键盘的方式。下面将为用户提供两种方式来收起键盘 :点击键盘上的 Return (返回)键
,或者点击 DetailViewController 视图的任意位置
。
第一响应者状态
UITextField 和 UITextView 对象响应触摸事件的方式与其他视图不同。 当收到触摸事件后 ,UITextField 或 UITextView 会成为第一响应者,然后让系统在屏幕上显示键盘 ,并且可以响应键盘的事件。键盘、 UITextField 或 UITextView 之间没有直接联系,它们通过第一响应者状态来配合工作 。
点击回车键来收起键盘
要实现点击回车键时收起键盘,可以实现
UITextFieldDelegate
的textFieldShouldReturn(_ :)
方法。点击回车键时,这个方法会被调用。如果点击应用中的另一个 UITextField, 那么它就会成为第一响应者,键盘仍然会显示在屏幕上。只有当所有 UITextField (或 UITextView ) 对象都不是第一响应者时,键盘才会消失。当 UITextField 是第一响应者时,可以调用
UITextField
的resignFirstResponder( )
来收起键盘。
- 首先,在 DetailViewController.swift 中,让 DetailViewController 实现 UITextFieldDelegate 协议。
class DetailViewController: UIViewController, UITextFieldDelegate {
- 下面实现 textFieldShouldReturn(_ :) 方法,在该方法中,调用 UITextField 的resignFirstResponder( ) 方法,代码如下:
func textFieldShouldReturn(_ textField: UITextField) -> Bool { //点击回车键时收起键盘
textField.resignFirstResponder() //点击回车键后会注销第一响应者,只有当所有 UITextField (或 UITextView ) 对象都不是第一响应者时,键盘才会消失。
return true
}
- 最后,打开 Main. storyboard , 并将所有 UITextField 的 delegate 属性和DetailViewController 连接起来。(按住 Control, 从 UITextField 拖到DetailViewController 上,然后选择
delegate
。)