iOS 10快速开发:18天零基础开发一个商业应用
上QQ阅读APP看书,第一时间看更新

icon

第3章 创建用户注册界面

在上一章,我们在故事板中创建了用户登录界面,并且还为登录视图与SignInVC代码类之间建立了Outlet和Action关联。本章我们将会创建用户的注册界面以及为注册界面和SignUpVC代码类创建相应的Outlet和Action关联。

3.1 利用滚动视图创建用户注册界面

大家都知道绝大部分应用的注册界面一般包含:用户名、密码、电子邮件等必填信息。下面我们将具体讲解如何创建注册界面。

步骤1 从对象库中拖曳一个Scroll View(滚动视图)到故事板中间的控制器视图,并调整其大小为整个屏幕的尺寸,如图3-1所示。

图3-1 在SignUpVC控制器视图中添加一个滚动视图

之所以在视图上添加一个滚动视图,是因为当用户在注册页面输入用户信息的时候,弹出的虚拟键盘会遮挡住底部的Text Field(尽管现在还没有创建它们),这将严重影响用户输入信息的体验。

Scroll View是用来在屏幕上显示那些在有限区域内放不下的内容。例如,在屏幕上显示内容丰富的网页或者表单,亦或是很大的图片。在这种情况下,需要用户对屏幕内容进行拖动或缩放来查看屏幕或窗口区域外的内容。

所以,Scroll View应该首先有一个窗口用来显示内容。其次,还要有内容本身。这个显示窗口就是Scroll View,这个窗口可以是整个手机屏幕,也可以只是手机屏幕的一部分区域。内容视图(Content View)则是需要填写的表单、查看的图片或者网页等信息的完整视图。通常,其大小会超过这个屏幕,正因为如此,我们才需要使用Scroll View,如图3-2所示。

图3-2 滚动视图和内容视图的区别

以图3-2为例,在滚动视图对象中,内容视图会储存完整的图片信息,而在滚动视图窗口中只会显示出一部分内容,我们必须借助平移手势来调整内容视图的偏移量(Content Offset),或者是通过掐捏手势调整内容视图的大小。

在滚动视图对象里有几个属性需要大家了解:

❑contentSize:它描述了有多大范围的内容需要使用Scroll View的窗口来显示,其默认值为CGSizeZero,也就是宽和高都是0。

当contentSize小于当前scrollView的大小时,意味着用户要显示的内容在窗口范围内是可以全部显示的。这时,通常内容视图是拖不动的(内容可以全部显示)。之所以说是“通常”,是因为通过某些设置,还是可以拖得动的,后面的滚动视图回弹机制里会解释。所以要让视图可以拖动,我们得设置一个contentSize。

❑contentOffset:描述了内容视图相对于Scroll View窗口的位置(相对于左上角的偏移量)。默认值是CGPointZero,也就是(0,0)。当视图被拖动时,系统会不断修改该值。也可以通过setContentOffset(_:animated:)方法让图片到达某个指定的位置。

❑contentInset:表示Scroll View的内边距,也就是内容视图边缘和Scroll View的边缘的留空距离,默认值是UIEdgeInsetsZero,也就是没间距。这个属性用得不多,通常

在需要刷新内容时才用得到。

步骤2 从对象库中拖曳一个Image View到滚动视图,在Size Inspector(快捷键“com-mand + option + 5”)中,将Width和Height均设置为80,然后将其移动到顶部水平居中的位置,如图3-3所示。

图3-3 在Scroll View上添加Image View

注意

由于没有设置Image View的自动布局约束,Xcode会提示缺少必要的约束。暂时不用管它,在之后的操作实践过程中,我们会通过代码的方式解决布局的问题。

步骤3 从资源文件夹中拖曳pp.jpg文件到项目之中,在弹出的添加文件选项面板中,确定勾选了Copy items if needed, Added folders为Create folder references, Add to targets的Instagram被勾选。

步骤4 回到Main.storyboard故事板,选中新添加的Image View,在Attributes Inspector中将image设置为pp.jpg, Image View立刻显示该图像内容。

步骤5 从对象库中拖曳七个Text Field到视图中,位置和大小如图3-4所示。

图3-4 添加7个Text Field控件

步骤6 同时选中这七个Text Field(按住command键,依次单击每个Text Field对象即可),在Attributes Inspector中将Clear Button设置为Is always visible。这样可以同时为七个Text Field设置同样的属性。

步骤7 只选中第一个Text Field,设置其Placeholder为用户名。接着选中第二个,将其设置为密码。然后依次设置为:重复密码、电子邮件、姓名、简介网站,如图3-5所示。

图3-5 设置Text Field属性

步骤8 同时选中密码重复密码两个Text Field,在Attributes Inspector中勾选上Secure Text Entry,因为我们要使用这两个Text Field输入密码。

步骤9 从对象库中拖曳一个Button到最后一个Text Field下方靠屏幕左侧的位置,宽度设置为70, Title设置为注册。再复制一个Button并将其拖曳到屏幕的右侧,将Title修改为取消。同时选中这两个Button,在Attributes Inspector中将Text Color修改为White Color。最后,将注册按钮的Background设置为橘黄色,将取消按钮的Background设置为亮灰色(Light Gray Color),如图3-6所示。

图3-6 设置Button的属性

3.2 创建Outlet和Action关联

要想实现用户交互的功能,必须创建Outlet和Action关联。

步骤1 将Xcode切换到助手编辑器模式,确定编辑区域中的上方窗口选中的是故事板中用户注册的视图,下方窗口会自动打开SignUpVC.swift文件。如果下方窗口中打开的不是相应文件的话,可以在导航区域中,按住option键并单击相应文件,以手动方式将其在下方窗口中打开。

步骤2 为注册视图中的控件对象创建Outlet关联,创建好以后,SignUpVC类中的Outlet属性应该有如下这些。

        class SignUpVC: UIViewController {
          //Image View,用于显示用户头像
          @IBOutlet weak var avaImg: UIImageView!
 
          // 用户名、密码、重复密码、电子邮件的Outlet关联
          @IBOutlet weak var usernameTxt: UITextField!
          @IBOutlet weak var passworTxt: UITextField!
          @IBOutlet weak var repeatPasswordTxt: UITextField!
          @IBOutlet weak var emailTxt: UITextField!
 
          // 姓名、简介、网站的Outlet关联
          @IBOutlet weak var fullnameTxt: UITextField!
          @IBOutlet weak var bioTxt: UITextField!
          @IBOutlet weak var webTxt: UITextField!
 
          // 滚动视图的Outlet关联
          @IBOutlet weak var scrollView: UIScrollView!

如果不方便对滚动视图(scrollView)进行Outlet关联操作的话,可以在大纲视图中拖曳相应的界面元素Item到SignUpVC类中,效果是完全一样的。对于复杂的用户界面来说,经常会用到这种方法。因为有些时候往往是几个视图嵌套在一起,或者是排列得很紧密,不方便直接进行拖曳,如图3-7所示。

图3-7 通过大纲视图创建Outlet关联

步骤3 在Outlet属性声明的下方,为SignUpVC类再添加一个属性scrollViewHeight变量,利用该属性可以在虚拟键盘出现和消失时,改变滚动视图contentSize属性的高度,使其向上滚动,从而提供更好的用户体验。

        @IBOutlet weak var scrollView: UIScrollView!
 
        // 根据需要,设置滚动视图的高度
        var scrollViewHeight: CGFloat = 0

大家可以想象,当用户单击Text Field以后会从屏幕底部滑出虚拟键盘,而键盘的高度正好会遮挡住位于下方的两个按钮和最下面的Text Field,这为我们信息的输入和检视带来了不小的麻烦。因此,本章在我们一开始设计用户界面的时候,就添加了滚动视图。当虚拟键盘出现时,可以增加滚动视图contentSize属性的高度,同时将需要显示的部分移动到虚拟键盘的顶部,这样就会给用户带来非常舒服的使用体验。

步骤4 在scrollViewHeight属性的下面再添加一个属性变量keyboard,利用该变量获取虚拟键盘在出现时候的大小。

        var scrollViewHeight: CGFloat = 0
 
        // 获取虚拟键盘的大小
        var keyboard: CGRect = CGRect()

该属性是CGRect结构体类型,它包含了矩形的位置和大小信息。如果你按住command键并单击CGRect的话,编辑窗口会直接跳转到CGRect的声明文件,从CGRect结构的声明中可以发现,它包含origin(CGPoint结构)和size(CGSize结构)两个重要属性。在iOS平台上,矩形用origin提供的点(矩形的左上角在父视图中的位置),再通过size属性提供的width和height来确定它的位置和大小。

步骤5 接下来,还要为按钮创建Outlet关联,在Outlet关联代码的下面,添加如下代码:

        // 为Button创建Outlet关联
        @IBOutlet weak var signUpBtn: UIButton!
        @IBOutlet weak var cancelBtn: UIButton!

熟悉iOS的朋友可能会这样问,我们一般通过按钮向代码类发送消息,因此只要为按钮创建Action关联就好,为什么这里还要创建Outlet关联呢?如果我们为按钮创建了自动布局约束的话,确实是这样的。但是在本书中,我们大部分的布局是通过代码实现的,所以需要相关界面对象在类中的Outlet引用。

步骤6 最后为两个按钮创建Action关联,方法名称分别为:signUpBtn_clicked和cancelBtn_clicked。

          // 注册按钮被单击
          @IBAction func signUpBtn_clicked(_ sender: AnyObject) {
            print("注册按钮被按下!")
          }
 
          // 取消按钮被单击
          @IBAction func cancelBtn_clicked(_ sender: AnyObject) {
            print("取消按钮被按下!")
          }

如果你仔细观察的话,会发现在编辑区域左侧的沟槽位置,每个Outlet和Action声明的位置都有一个圆圈,它可以是空心的,也可以是实心的,如图3-8所示。那它代表什么意思呢?

图3-8 Outlet和Action的状态

当你在类文件中创建了Outlet或Action代码,但是该属性或者方法并没有与故事板中的界面对象建立关联的时候,圆圈就是空心的,否则就是实心的。

构建并运行项目,在单击不同按钮的时候,调试控制台中会输出不同的文本信息。当然,光是单纯的输出文本信息还是不够的,最起码在用户单击取消按钮以后,SignUpVC控制器应该被取消,它的视图应该消失,屏幕上应该呈现之前的登录视图。

3.3 让注册视图消失

让当前视图消失,实际上就是要销毁当前的视图控制器,因此需要使用控制器类的dismiss(animated:completion:)方法。

在cancelBtn_clicked(_:)方法的内部,print语句的下面添加一行代码:

          // 以动画的方式去除通过modally方式添加进来的控制器
          self.dismiss(animated: true, completion: nil)

假设我们需要在View Controller A中呈现View Controller B,那么A就充当Presenting View Controller(弹出VC)的角色,而B就是Presented View Controller(被弹出VC)。当需要除去Presented View Controller(View Controller B)的时候,则要在Presenting View Controller (View Controller A)中执行dismiss(animated: completion:)方法,如果是在Presented View Controller调用dismiss(animated: completion:)方法的话,同样会通过Presenting View Controller的dismiss(animated: completion:)方法进行处理。

另外,如果我们连续呈现几个view controller,系统则会构建一个堆栈。如果在控制器堆栈的某个层级执行dismiss方法的话,它的即时子控制器和其上的所有控制器均会被去除。但只有在即时子控制器的视图会根据animated参数进行动画,其他的控制器则被直接去除。

构建并运行项目,在登录视图中单击注册按钮以后会呈现注册视图,在注册视图中单击取消按钮以后,注册视图消失,SignUpVC控制器被销毁。此时,屏幕会呈现登录视图。

本章小结

当所要显示的内容大于屏幕尺寸的时候,往往会用到滚动视图。本章我们在搭建注册用户界面的时候使用了滚动视图,还有很多视图都继承于滚动视图,比如表格视图(Table View)、集合视图(Collection View)和文本视图(Text View)等。