apple store开发上架推广:

实现一个自定义的控制(第四篇)

在本课中,您将执行的foodtracker APP分级控制。当你完成后,你的应用程序看起来就像这样:

学习目标

at the end of the课程,你将能够:

  • 创建和使用故事板中的元素把自定义的源代码文件

  • 定义一个自定义类

  • 实现一个自定义类初始化器

  • 使用uistackview作为一个容器

  • 了解如何创建视图时

  • 添加辅助信息的自定义控件

  • 工作“ibinspectable和“ibdesignable显示和控制界面中的自定义视图

创建一个自定义视图

能够率一顿,用户需要一个控制装置让他们选择明星他们要分配给饭的数量。有很多方法可以实现,但这课集中于一个简单的方法,结合现有的视图和控件创建一个自定义的控制。你会创建一个堆栈视图类管理一行代表星星按钮。你完全是在代码中定义自定义控件,然后将其添加到你的故事板。

额定控制为一排星星。

用户可以选择一个吃饭的评级。当用户点击一个明星,明星和它前面的星星了。如果用户点击最右边的填星(与额定电流有关的星),评级被清除,所有的星星都显示为空。

开始设计用户界面(UI),互动,和行为的控制,首先创建一个自定义堆栈视图(uistackview)子类。

创建一个类uistackview

  1. 选择文件>新建>文件(或按了N命令)。

  2. 在出现的对话框的顶部,选择iOS。

  3. 选择Cocoa Touch的类,然后单击“下一步”。

  4. in the class字段类型ratingcontrol。

  5. 在“类”,选择uistackview。

  6. 确保语言选项设置为快捷。

  7. 单击“下一步”。

    保存位置默认为你的项目目录。

    这组选项默认为您的应用程序的名字,FoodTracker。

    在目标部分,你的应用程序选择并为你的应用程序的测试选择。

  8. 离开这些默认设置它们,然后点击创建。

    Xcode创建一个文件定义ratingcontrol类ratingcontrol.swift。ratingcontrol是一个自定义的视图类UIView。

  9. 如果有必要,在项目导航,拖动ratingcontrol.swift文件以便它位于其他文件下迅速。

  10. 进入ratingcontrol.swift,删除与模板的评论实施所以你可以从一个空白的工作。

    实施看起来应该像这样:

  11. 进口UIKit

  12. 类ratingcontrol:uistackview{

  13. }

你通常会创建一个视图的方式有两种:通过编程方式初始化的观点,或通过允许视图是由脚本加载。有一个相应的每个方法初始化:init(框架)在程序初始化视图初始化?(编码:)从故事板加载视图。回想起初始化一类是准备用实例的方法,其中包括设置各个属性的初始值和执行其他的安装。

你将需要实现这些方法在你的自定义控件。在设计应用程序,界面生成器程序实例化视图时,你将它添加到画布。在运行时,应用程序加载从情节提要视图。

重写的初始化

  1. 进入ratingcontrol.swift,下类线,添加评论。

  2. / /马克:初始化

  3. 下面的评论,开始打字初始化。

    代码完成叠加显示。

  4. 选择init(框架:CGRect)从列出的选项,并按回车。

    Xcode插件初始化骨架为你。

  5. 初始化(帧:CGRect){

  6. }

  7. 错误和警告显示为黄色的三角形图标(警告)和红圈(错误)旁边的代码。目前,该init(框架)方法有一个错误。点击错误图标调出有关错误的更多信息。

  8. 双击修复它插入重写关键词

    斯威夫特编译器知道init(框架)必须标注的要求,并提供了一个修复它使代码中的变化。解决它由编译器提供的代码中的错误可能的解决方案。

  9. 重写初始化(帧:CGRect){

  10. }

  11. 这一行添加到调用父类的初始化:

  12. 超级的。初始化(帧:帧)

  13. 下面的init(框架)方法,开始打字初始化再次,选择init(编:NSCoder)从代码完成选项。按返回。

    Xcode插件初始化骨架为你。

  14. 初始化(编码器:NSCoder){

  15. }

  16. 使用固定插入要求关键词

    笔记

    迅速的处理不同于其他方法初始化。如果你不提供任何初始化,斯威夫特类自动继承其超类的所有指定的初始化。如果你执行任何初始化,你不再承受任何的超类的初始化;然而,父类可以标记一个或多个其初始化为要求。子类必须实现(或自动继承)所需的所有初始化。此外,子类必须标记为初始化要求,表明他们的子类必须实现初始化。

  17. 这一行添加到调用父类的初始化。

  18. 超级的。初始化(编码器:编码器)

初始化器看起来应该像这样:

  1. 重写初始化(帧:CGRect){

  2. 超级的。初始化(帧:帧)

  3. }

  4. 要求初始化(编码器:NSCoder){

  5. 超级的。初始化(编码器:编码器)

  6. }

现在,你的初始值为占位符,简单地调用父类的实现。您将添加额外的配置步骤在本课之后。

显示自定义视图

显示您的自定义控件,你需要添加一个栈查看你的故事板和建立堆栈视图和你写的代码之间的连接。

显示视图

  1. 打开你的故事。

  2. 在你的故事板,使用对象库找到一个水平叠加的视图对象,并拖动一个进入你的故事的场景,这是在下面的图像查看堆栈视图。

  3. 与水平叠加选择视图,打开身份检查器

    记得,身份检查让你在你的故事板编辑该对象的身份相关的对象的属性,如什么类的对象属于。

  4. 在身份检查,发现现场标记类和选择ratingcontrol。

将按钮添加到视图

在这一点上,你有一个自定义的基础知识uistackview的子类,称为ratingcontrol。接下来,你需要将按钮添加到您的视图允许用户选择一个等级。先从简单的开始,比如一个红色的按钮,显示在您的视图。

创建视图按钮

确保添加到按钮,无论哪个初始化为。要做到这一点,添加一个私有方法,setupbuttons(),并从初始化调用这个方法。

  1. 进入ratingcontrol.swift,初始化方法下,添加评论。

    使用下面的空间评论创建私有方法私人改性剂之前功能介绍人。私有方法只能调用的代码在声明类。这让你封装和保护方法,确保他们不是意外或不小心被从外面。

  2. / /马克:私有方法

  3. 在评论中,添加下面的方法:

  4. 私人功能setupbuttons(){

  5. }

  6. 在setupbuttons()方法,添加下面的代码创建一个红色的按钮:

    在这里,你使用的是一体的UIButton类初始化的便利。此初始化调用init(框架)通过在一零大小的矩形。从一零大的按钮是好的,因为你使用自动布局。堆栈视图将自动定义按钮的位置,你会添加约束来定义按钮的大小。

    你用的是红色所以很容易看到的视图。如果你愿意,用另一个预定义的UIColor价值观相反,像蓝色或植物。

  7. /“Create按钮

  8. 让按钮 = UIButton()

  9. 按钮。背景色 = UIColor。红色

  10. 在最后一行的下面,添加按钮的约束:

    第一行代码禁用按钮的自动生成的约束。当你通过程序实例化一个视图,其translatesautoresizingmaskintoconstraints属性的默认值为真正的。这告诉布局引擎创建约束定义视图的大小和基于视图的位置帧和autoresizingmask性能通常情况下,当你使用自动布局,你想替换你自己这些自动生成的约束。删除自动生成的约束集translatesautoresizingmaskintoconstraints属性假。

    笔记

    这条线是完全没有必要的。当你添加一个视图到堆栈,堆栈视图自动设置视图的translatesautoresizingmaskintoconstraints属性假。然而,使用自动布局时,显式禁用自动生成的约束,当你以编程方式创建一个视图是一个很好的习惯。这样你就不会不小心忘记禁用它们,当它实际上事项。

    开始的行button.heightanchor和button.widthanchor创建定义按钮的高度和宽度的限制。每一行执行以下步骤:

    在一起,这些线定义的按钮在你的布局一个固定大小的对象(44点×44点)。

  11. 按钮的heightanchor和widthanchor属性提供了布局的锚。你使用布局锚在这种情况下创建约束,约束定义视图的高度和宽度,分别。

  12. 锚的约束(equaltoconstant:)方法返回一个约束定义的角度恒定的高度或宽度。

  13. 约束的活跃属性来启用或禁用约束。当你设置这个属性真正的,该系统增加了约束,正确的观点,并激活它。

  14. / /添加约束

  15. 按钮。translatesautoresizingmaskintoconstraints = 假

  16. 按钮。heightanchor。约束(equaltoconstant:四十四)。活跃 = 真正的

  17. 按钮。widthanchor。约束(equaltoconstant:四十四)。活跃 = 真正的

  18. 最后,将按钮添加到堆栈:

    这个addarrangedsubview()方法将创建托管的视图列表按钮ratingcontrol堆栈视图。这一行动将视图的子视图ratingcontrol,并指示ratingcontrol创造需要在控制管理按钮的位置约束。

  19. //将按钮添加到堆栈

  20. addarrangedsubview(按钮)

你的setupbuttons()方法应该是这样的:

  1. 私人功能setupbuttons(){

  2. /“Create按钮

  3. 让按钮 = UIButton()

  4. 按钮。背景色 = UIColor。红色

  5. / /添加约束

  6. 按钮。translatesautoresizingmaskintoconstraints = 假

  7. 按钮。heightanchor。约束(equaltoconstant:四十四)。活跃 = 真正的

  8. 按钮。widthanchor。约束(equaltoconstant:四十四)。活跃 = 真正的

  9. //将按钮添加到堆栈

  10. addarrangedsubview(按钮)

  11. }

现在调用此方法从初始化方法,如下图所示:

  1. 重写初始化(帧:CGRect){

  2. 超级的。初始化(帧:帧)

  3. setupbuttons()

  4. }

  5. 要求初始化(编码器:NSCoder){

  6. 超级的。初始化(编码器:编码器)

  7. setupbuttons()

  8. }

检查点:运行你的应用程序。你应该能够看到一个在它里面的一个小红场。红场是你添加在初始化按钮。

你需要为这个按钮添加一个动作(和你会添加其他的按钮)。最后,您将使用此按钮改变膳食的评级然而,现在你只会检查行动工作。

添加一个动作按钮

  1. 进入ratingcontrol.swift,后/ /标志初始化添加下面的部分:

  2. / /马克:按钮操作

  3. 在评论中,添加以下:

    使用print()功能检查,ratingbuttontapped(_:)行动是与预期的按钮。这个函数将消息输出到标准输出,在这种情况下是Xcode调试控制台。控制台是一个有用的调试机制在编辑区的底部出现。

    你会更换调试实现的一点真正的实现而。

  4. 功能ratingbuttontapped(按钮:UIButton){

  5. 打印(”按钮”)

  6. }

  7. 找到setupbuttons()方法

  8. 私人功能setupbuttons(){

  9. /“Create按钮

  10. 让按钮 = UIButton()

  11. 按钮。背景色 = UIColor。红色

  12. / /添加约束

  13. 按钮。translatesautoresizingmaskintoconstraints = 假

  14. 按钮。heightanchor。约束(equaltoconstant:四十四)。活跃 = 真正的

  15. 按钮。widthanchor。约束(equaltoconstant:四十四)。活跃 = 真正的

  16. //将按钮添加到堆栈

  17. addarrangedsubview(按钮)

  18. }

  19. 正上方//将按钮添加到堆栈评论,添加以下代码:

    在上一课中,您使用的目标行为模式的链接元素在你的脚本代码中的行动方法。这个addtarget(_,动作:方法:)方法在代码中做同样的事情。你将ratingbuttontapped(_:)动作方法的按钮对象,它将被触发时着陆。事件发生。

    有许多的事情在这个代码。这里有一个击穿:

  • 目标是自己,这是指外围类的当前实例。在这种情况下,它指的是ratingcontrol对象,设置按钮。

  • 这个#选择器表达式返回选择器对所提出的方法的价值。一个选择器标识方法的不透明值。旧的API使用选择器来动态调用的方法在运行时。而新的API已经很大程度地取代了选择器与块、多方法performselector(_:)和addtarget(_ forcontrolevents:动作::)-还带选择器作为参数。在这个例子中,该#选择器(ratingcontrol。ratingbuttontapped(_:))表达式返回你的选择ratingbuttontapped(_:)动作方法。这让系统调用你的动作方法当按钮被窃听。

  • 这个uicontrolevents选项集定义了一系列控制可以对事件做出反应。典型的按钮响应的touchupinside。事件这发生在当用户触摸按钮,然后举起手指,手指仍在按钮的界限。这一事件具有优势着陆。,因为用户可以通过拖动手指在按钮之前解除取消事件。

  • 请注意,因为你没有使用界面生成器,你不需要和定义你的动作方法ibaction属性;你只是定义的动作像任何其他的方法。你可以使用一个方法不需要参数,以一个发送者的说法,或者说需要发送方和事件参数。

  1. 功能做的事()

  2. 功能做的事(发件人:UIButton)

  3. 功能做的事(发件人:UIButton,事件事件:UIEvent)

  4. / /设置按钮的动作

  5. 按钮。addtarget(自己,行动:#选择器(ratingcontrol。ratingbuttontapped(按钮:)),为:。touchupinside)

你的setupbuttons()方法应该是这个样子的:

  1. 私人功能setupbuttons(){

  2. /“Create按钮

  3. 让按钮 = UIButton()

  4. 按钮。背景色 = UIColor。红色

  5. / /添加约束

  6. 按钮。translatesautoresizingmaskintoconstraints = 假

  7. 按钮。heightanchor。约束(equaltoconstant:四十四)。活跃 = 真正的

  8. 按钮。widthanchor。约束(equaltoconstant:四十四)。活跃 = 真正的

  9. / /设置按钮的动作

  10. 按钮。addtarget(自己,行动:#选择器(ratingcontrol。ratingbuttontapped(按钮:)),为:。touchupinside)

  11. //将按钮添加到堆栈

  12. addarrangedsubview(按钮)

  13. }

检查点:运行你的应用程序。当你点击红场,您应该看到“按钮”在控制台消息。

现在是时候想想什么样的信息ratingcontrol类需要为了表示评级。你需要跟踪评级的价值,以及用户点击设置按钮,评级。你可以用一个代表值int,和按钮的数组UIButton目标

添加额定性能

  1. 进入ratingcontrol.swift,找到类声明线:

  2. 类ratingcontrol:UIView{

  3. 在这条线的下面,添加以下代码:

    这样就产生了两个性质。首先是一个属性包含按钮的列表。你不想让任何外ratingcontrol类访问这些按钮;因此,你将它们声明为私有。

    第二属性包含等级控制的。你需要能够读取和从外面这类写这个值。让它作为内部访问(默认的),你可以从任何其他类应用程序中访问它。

  4. / /马克:性能

  5. 私人VaRratingbuttons = [UIButton]()

  6. VaR评级 = 零

现在,你在看一个按钮,但是你需要五的总。创建一个共有五个按键,使用为—进入环。一为—进入循环遍历一个序列,如数字范围,执行一组代码多次。而不是创建一个按钮,循环将创造五。

创建一个共有五个按钮

  1. 进入ratingcontrol.swift,找到setupbuttons()方法,并添加一个为—进入在法的内容循环,这样:

    确保在线路为—进入环是正确选择缩进都压control-i.

    这个半开放的操作范围(<……)不包括上面的数字,所以这个范围从零到四总共五个循环迭代,绘制五个按钮而不是一个。下划线(_)是一个通配符,你可以用它的时候,你不需要知道哪些循环迭代的当前正在执行的。

  2. 为_进入零..<五{

  3. /“Create按钮

  4. 让按钮 = UIButton()

  5. 按钮。背景色 = UIColor。红色

  6. / /添加约束

  7. 按钮。translatesautoresizingmaskintoconstraints = 假

  8. 按钮。heightanchor。约束(equaltoconstant:四十四)。活跃 = 真正的

  9. 按钮。widthanchor。约束(equaltoconstant:四十四)。活跃 = 真正的

  10. / /设置按钮的动作

  11. 按钮。addtarget(自己,行动:#选择器(ratingcontrol。ratingbuttontapped(按钮:)),为:。touchupinside)

  12. //将按钮添加到堆栈

  13. addarrangedsubview(按钮)

  14. }

  15. 添加下面的正上方,在环的花括号(})。

    当你创建每个按钮,你把它添加到ratingbuttons阵列来保持它的轨道。

  16. / /添加新的按钮,按钮阵列的评级

  17. ratingbuttons。追加(按钮)

你的setupbuttons()方法应该是这个样子的:

  1. 私人功能setupbuttons(){

  2. 为_进入零..<五{

  3. /“Create按钮

  4. 让按钮 = UIButton()

  5. 按钮。背景色 = UIColor。红色

  6. / /添加约束

  7. 按钮。translatesautoresizingmaskintoconstraints = 假

  8. 按钮。heightanchor。约束(equaltoconstant:四十四)。活跃 = 真正的

  9. 按钮。widthanchor。约束(equaltoconstant:四十四)。活跃 = 真正的

  10. / /设置按钮的动作

  11. 按钮。addtarget(自己,行动:#选择器(ratingcontrol。ratingbuttontapped(按钮:)),为:。touchupinside)

  12. //将按钮添加到堆栈

  13. addarrangedsubview(按钮)

  14. / /添加新的按钮,按钮阵列的评级

  15. ratingbuttons。追加(按钮)

  16. }

  17. }

检查点:运行你的应用程序。注意堆栈视图列出了按钮。他们是水平放置的,但是两者之间没有空间,使他们看起来像一个单一的,红块。

为了解决这个问题,打开main.storyboard并选择ratingcontrol堆栈视图。打开属性检查

,设置间距属性八。

检查点:再次运行你的应用程序。现在,按钮应如预期。注意,点击任何按钮,此时仍应调用ratingbuttontapped(按钮)方法和日志消息到控制台。

崩溃的控制台,使用调试区域切换。

添加界面生成器支持

如果你看看在Interface Builder的等级控制,你会发现,它显示为一个大的、空的矩形。更糟糕的是,如果你选择的等级控制,其框变成红色,说明有控件的布局问题。事实上,有两个其他标志的东西可能是错的。在活动查看器右侧黄色三角警示。还有一个红色错误图标旁边的视图控制器的场景在大纲视图。

如果你点击这些图标,Xcode显示错误和警告的附加信息。

在这两种情况下,最根本的原因是一样的。界面生成器不知道你的等级控制的内容的东西。为了解决这个问题,你定义的控制“ibdesignable。这让界面生成器实例化并直接在画布上绘制一份你的控制。此外,现在界面生成器有活拷贝你的控制,它的布局引擎可以适当位置和大小的控制。

申报为“ibdesignable控制

  1. 进入ratingcontrol.swift找茶类的声明:

  2. 类ratingcontrol:uistackview{

  3. 添加“ibdesignable对线如图所示的开始:

  4. “ibdesignable类ratingcontrol:uistackview{

  5. 通过键入command-b危改项目(或选择产品>建立)。

  6. 开放main.storyboard。一旦构建完成,故事板显示现场查看你的等级控制。

    注意:画布大小和你现在正确的地方ratingcontrol意见作为一个结果,警告和错误消失了。

Interface Builder可以做的不仅仅是显示你的自定义视图。你也可以指定,可以在属性检查器属性。添加“ibinspectable属性所需的性能。界面生成器支持基本类型检查(及其相应的可选项),包括:数字、字符串、布尔值、以及CGRect,cgsize,cgpoint,和UIColor。

添加检测性能

  1. 进入ratingcontrol.swift,在底部添加以下属性/ /马克:性能部分:

    这些线定义你的按钮的大小和你的控制按钮的数量。

  2. “ibinspectableVaRstarsize:cgsize = cgsize(宽度:四十四,高度:四十四)

  3. “ibinspectableVaRStarCount:int = 五

  4. 现在你需要使用这些值。定位setupbuttons()方法,并进行以下更改:

    该方法应该出现如下图所示:

    如果你切换到main.storyboard并选择ratingcontrol,你会看到恒星的大小和在属性检查器中的星数设置。虚线表明控制当前使用的是默认值(在这种情况下,44分和5分)。然而,更改这些值不变化的控制。

  5. 私人功能setupbuttons(){

  6. 为_进入零..<StarCount{

  7. /“Create按钮

  8. 让按钮 = UIButton()

  9. 按钮。背景色 = UIColor。红色

  10. / /添加约束

  11. 按钮。translatesautoresizingmaskintoconstraints = 假

  12. 按钮。heightanchor。约束(equaltoconstant:starsize。高度)。活跃 = 真正的

  13. 按钮。widthanchor。约束(equaltoconstant:starsize。宽度)。活跃 = 真正的

  14. / /设置按钮的动作

  15. 按钮。addtarget(自己,行动:#选择器(ratingcontrol。ratingbuttontapped(按钮:)),为:。touchupinside)

  16. //将按钮添加到堆栈

  17. addarrangedsubview(按钮)

  18. / /添加新的按钮,按钮阵列的评级

  19. ratingbuttons。追加(按钮)

  20. }

  21. }

  22. 在为—进入宣言,改变五到StarCount。

  23. 在按钮。heightanchor。constraint()调用方法的变化四十四到starsize.height。

  24. 在按钮。widthanchor。constraint()调用方法的变化四十四到starsize.width。

  25. 更新控制,你需要重置控制按钮每次这些属性的改变。要做到这一点,添加一个属性,每个属性的观察者。一性能观察观察和对属性值的变化。房地产观察家称每次属性值的设置,可以使用之前或之后立即执行工作的价值变化。

    进入ratingcontrol.swift,如下图所示修改检测性能:

    在这里,你定义的性能观察starsize和StarCount性能具体而言,该didset产权是财产的价值观察后将立即打电话。你的实现,然后调用setupbuttons()方法这种方法增加了新的按钮使用更新的大小和数量;然而,当前实现不摆脱旧的按钮。

  26. “ibinspectableVaRstarsize:cgsize = cgsize(宽度:四十四,高度:四十四){

  27. didset{

  28. setupbuttons()

  29. }

  30. }

  31. “ibinspectableVaRStarCount:int = 五{

  32. didset{

  33. setupbuttons()

  34. }

  35. }

  36. 清除旧的按钮,添加下面的代码的开始setupbuttons()方法

    此代码遍历所有评级的控制按钮。首先,它删除按钮从堆栈视图管理视图列表。这告诉堆栈视图应该不再计算按钮的大小和位置的按钮,但仍然是一个视图的堆栈视图。接下来的代码删除按钮从栈查看全部。最后,一旦所有的按钮已被移除,它清除ratingbuttons阵列。

    这个setupbuttons()方法现在应该出现如下图所示:

    笔记

    拆除和更换所有的按钮是不是一定要从性能的角度来看,最好的主意。然而,这didset观察家们应该只被界面生成器在设计时。当应用程序运行时,该setupbuttons()方法只被调用一次,当第一次加载的脚本控制。因此,没有必要创造更新的地方存在的按钮,一个更复杂的解决方案。

  37. 私人功能setupbuttons(){

  38. / /清除任何现有的按钮

  39. 为按钮进入ratingbuttons{

  40. removearrangedsubview(按钮)

  41. 按钮。removeFromSuperview()

  42. }

  43. ratingbuttons。移除所有()

  44. 为_进入零..<StarCount{

  45. /“Create按钮

  46. 让按钮 = UIButton()

  47. 按钮。背景色 = UIColor。红色

  48. / /添加约束

  49. 按钮。translatesautoresizingmaskintoconstraints = 假

  50. 按钮。heightanchor。约束(equaltoconstant:starsize。高度)。活跃 = 真正的

  51. 按钮。widthanchor。约束(equaltoconstant:starsize。宽度)。活跃 = 真正的

  52. / /设置按钮的动作

  53. 按钮。addtarget(自己,行动:#选择器(ratingcontrol。ratingbuttontapped(按钮:)),为:。touchupinside)

  54. //将按钮添加到堆栈

  55. addarrangedsubview(按钮)

  56. / /添加新的按钮,按钮阵列的评级

  57. ratingbuttons。追加(按钮)

  58. }

  59. }

  60. / /清除任何现有的按钮

  61. 为按钮进入ratingbuttons{

  62. removearrangedsubview(按钮)

  63. 按钮。removeFromSuperview()

  64. }

  65. ratingbuttons。移除所有()

检查点开放main.storyboard并选择ratingcontrol目标尝试改变恒星大小和星数的属性。在画布上的控制应改变以适应新的环境。运行的应用程序,你应该看到在模拟器中的变化。

要确保这些设置重置为其默认值,当你做测试。

进一步探讨

在自定义视图工作的更多信息,参见奠定了用户界面>添加对象和媒体>渲染在Xcode帮助自定义视图。

加星图像按钮

接下来,您将添加一个空的,填充的图像,并强调了明星的按钮。

你可以找到上面显示的图像图像本课的最后的可下载文件的文件夹,或使用自己的图片。(确保你用火柴在后面的代码,图像名称形象的名字)

图像添加到您的项目

  1. 在项目导航,选择assets.xcassets查看资产目录。

    记得,资产目录是一个地方来存储和组织你的形象资产的应用。

  2. 在左下角,点击加号( )按钮,从弹出菜单中选择新的文件夹。

  3. 双击文件夹的名字命名评级图片。

  4. 在选定的文件夹中,在左下角,点击加号( )按钮,选择新的图像设置弹出菜单。

    一个图像集代表一个图像资产,但可以包含不同的图像版本显示在不同的屏幕分辨率。

  5. 双击图像集的名字命名“emptystar”。

  6. 在您的计算机上,选择空的明星形象要添加。

  7. 拖放图片到2X在图像设置槽。

    2X是显示分辨率的iPhone 7模拟器,你在这些课程中使用,使图像看起来是最好的在这个决议。

  8. 在左下角,点击加号( )按钮,选择新的图像设置弹出菜单。

  9. 双击图像集的名字命名“filledstar”。

  10. 在您的计算机上,选择了明星形象要添加。

  11. 拖放图片到2X在图像设置槽。

  12. 在左下角,点击加号( )按钮,选择新的图像设置弹出菜单。

  13. 双击图像集的名字命名“highlightedstar”。

  14. 在您的计算机上,选择了明星形象要添加。

  15. 拖放图片到2X在图像设置槽。

你的资产目录应该是这个样子:

其次,编写代码来设置在合适的时间合适的图像按钮。

为按钮设置星图

  1. 进入ratingcontrol.swift,浏览到setupbuttons()方法,并将该代码的正上方为—进入循环,创建按钮:

    这些线路负荷的星空图像,从资产目录。请注意,资产目录位于应用程序主束。这意味着应用程序可以加载图像使用短UIImage(命名为:)方法然而,由于控制“ibdesignable,设置代码也需要运行在界面生成器。在界面中正确加载图像,您必须显式指定目录的束。这保证了系统可以找到并加载图像。

  2. 按钮/ Load Images)

  3. 让束 = 束(为:类型(属于:自己))

  4. 让“filledstar” = UIImage(命名:“filledstar”,进入:束,兼容:自己。traitcollection)

  5. 让“emptystar” = UIImage(命名:“emptystar”,进入:束,兼容:自己。traitcollection)

  6. 让“highlightedstar” = UIImage(命名:“highlightedstar”,进入:束,兼容:自己。traitcollection)

  7. 查找线路,设置背景颜色(button.backgroundColor = UIColor.redColor())和取代它的下面:

    按钮有五种不同的状态:正常、突出、集中,选择,和残疾人。默认情况下,按钮的基础上修改它的状态出现,例如禁用的按钮显示为灰色。一个按钮可以同时处于多个状态,如当一个按钮是残疾人和突出。

    按钮开始总是在正常状态下(不突出,选择,集中,或禁用)。一个按钮是强调当用户触摸它。你也可以通过编程设置一个按钮来选择或禁用。聚焦状态的焦点基于接口的使用,像苹果电视。

    在上面的代码中,你说的是按钮的正常状态使用空的明星形象。这是按钮的默认图像。系统使用的图像(可能有附加效果)当一个国家或联合国没有自己的形象。

    其次,上述设置选定状态填充图像的编码。如果你以编程方式设置按钮的选择,它将从空星改变填充的明星。

    最后,你的选择和突出强调和突出图像的状态集。当用户触摸按钮,它是否被选中,系统会显示高亮显示的按钮图像。

  8. 按钮/看Images)

  9. 按钮。西雅图(“emptystar”,为:。正常)

  10. 按钮。西雅图(“filledstar”,为:。挑选)

  11. 按钮。西雅图(“highlightedstar”,为:。突出)

  12. 按钮。西雅图(“highlightedstar”,为:[。突出,。挑选])

你的setupbuttons()方法应该是这样的:

  1. 私人功能setupbuttons(){

  2. / /清除任何现有的按钮

  3. 为按钮进入ratingbuttons{

  4. removearrangedsubview(按钮)

  5. 按钮。removeFromSuperview()

  6. }

  7. ratingbuttons。移除所有()

  8. 按钮/ Load Images)

  9. 让束 = 束(为:类型(属于:自己))

  10. 让“filledstar” = UIImage(命名:“filledstar”,进入:束,兼容:自己。traitcollection)

  11. 让“emptystar” = UIImage(命名:“emptystar”,进入:束,兼容:自己。traitcollection)

  12. 让“highlightedstar” = UIImage(命名:“highlightedstar”,进入:束,兼容:自己。traitcollection)

  13. 为_进入零..<StarCount{

  14. /“Create按钮

  15. 让按钮 = UIButton()

  16. 按钮/看Images)

  17. 按钮。西雅图(“emptystar”,为:。正常)

  18. 按钮。西雅图(“filledstar”,为:。挑选)

  19. 按钮。西雅图(“highlightedstar”,为:。突出)

  20. 按钮。西雅图(“highlightedstar”,为:[。突出,。挑选])

  21. / /添加约束

  22. 按钮。translatesautoresizingmaskintoconstraints = 假

  23. 按钮。heightanchor。约束(equaltoconstant:starsize。高度)。活跃 = 真正的

  24. 按钮。widthanchor。约束(equaltoconstant:starsize。宽度)。活跃 = 真正的

  25. / /设置按钮的动作

  26. 按钮。addtarget(自己,行动:#选择器(ratingcontrol。ratingbuttontapped(按钮:)),为:。touchupinside)

  27. //将按钮添加到堆栈

  28. addarrangedsubview(按钮)

  29. / /添加新的按钮,按钮阵列的评级

  30. ratingbuttons。追加(按钮)

  31. }

  32. }

检查点:运行你的应用程序。你应该看到星星而不是红色的按钮。点击任何按钮,在这一点上还是要打ratingbuttontapped(_:)和日志消息到控制台。你甚至可以看到蓝色的星在你触摸按钮,但你却没有改变填充图像。你会下。

实现按钮的动作

用户需要能够通过点击一个明星选择一个等级,所以你会有真正的执行更换调试的实现ratingbuttontapped(_:)方法

实施评级行动

  1. 进入ratingcontrol.swift,找到ratingbuttontapped(按钮)方法

  2. 功能ratingbuttontapped(按钮:UIButton){

  3. 打印(”按钮”)

  4. }

  5. 更换打印这个代码语句:

    在上面的代码中,该indexof(_:)方法尝试在按钮数组找到所选按钮,返回索引在它被发现。此方法返回一个可选int因为你找的实例可能不存在在你的收集搜索。然而,由于触发这一行动的唯一按钮是你创建并添加到阵列的,如果indexof(_:)方法无法找到匹配的按钮,您的代码中有一个严重的错误。投掷一个致命的错误在这里终止应用程序和打印一个有用的错误消息到控制台,帮助你发现并解决任何问题,你的设计和测试您的应用程序。

    一旦你的按钮的索引(在这种情况下,价值从0到4),就增加1的指数来计算所选评(给你从1到5的值)。如果用户点击对应的额定电流的明星,你重置控制评级属性为0。否则,你将评级所选评。

  6. 功能ratingbuttontapped(按钮:UIButton){

  7. 警卫让指数 = ratingbuttons。指数(属于:按钮)其他的{

  8. 致命错误(“)

  9. }

  10. //计算该等级的选择按钮

  11. 让selectedrating = 指数一

  12. 如果selectedrating == 评级{

  13. //如果选定的明星代表的额定电流,重置等级0。

  14. 评级 = 零

  15. }其他的{

  16. 另有/看到评级的选星

  17. 评级 = selectedrating

  18. }

  19. }

  20. 一旦等级设置,你需要一些方法来更新按钮的外观。进入ratingcontrol.swift最后,在大括号(}),添加以下方法:

    这是一个你可以使用更新按钮的选择状态的辅助方法。

  21. 私人功能updatebuttonselectionstates(){

  22. }

  23. 在updatebuttonselectionstates()方法,添加以下为—进入环:

    此代码遍历按钮和设置每一个选定的国家基于其地位和等级。当你看到的时候,选择状态影响按钮的外观。如果按钮的指数低于评级的选择属性设置为真正的,和按钮显示的图像填充的明星。否则,选择属性设置为假,和按钮显示空的明星形象。

  24. 私人功能updatebuttonselectionstates(){

  25. 为(指数,按钮)进入ratingbuttons。枚举(){

  26. /如果一个按钮的指数低于评级,按钮,应选择。

  27. 按钮。选择 = 指数 < 评级

  28. }

  29. }

  30. 添加一个属性观察到评级财产,并调用updatebuttonselectionstates()方法时,评级变化。

  31. VaR评级 = 零{

  32. didset{

  33. updatebuttonselectionstates()

  34. }

  35. }

  36. 你也需要更新按钮的选择状态时,按钮将添加到控制。在setupbuttons()添加一个调用的方法,updatebuttonselectionstates()方法只是方法上的花括号(})。thesetupbuttons()方法现在看起来应该如下图所示:

  37. 私人功能setupbuttons(){

  38. / /清除任何现有的按钮

  39. 为按钮进入ratingbuttons{

  40. removearrangedsubview(按钮)

  41. 按钮。removeFromSuperview()

  42. }

  43. ratingbuttons。移除所有()

  44. 按钮/ Load Images)

  45. 让束 = 束(为:类型(属于:自己))

  46. 让“filledstar” = UIImage(命名:“filledstar”,进入:束,兼容:自己。traitcollection)

  47. 让“emptystar” = UIImage(命名:“emptystar”,进入:束,兼容:自己。traitcollection)

  48. 让“highlightedstar” = UIImage(命名:“highlightedstar”,进入:束,兼容:自己。traitcollection)

  49. 为指数进入零..<StarCount{

  50. /“Create按钮

  51. 让按钮 = UIButton()

  52. 按钮/看Images)

  53. 按钮。西雅图(“emptystar”,为:。正常)

  54. 按钮。西雅图(“filledstar”,为:。挑选)

  55. 按钮。西雅图(“highlightedstar”,为:。突出)

  56. 按钮。西雅图(“highlightedstar”,为:[。突出,。挑选])

  57. / /添加约束

  58. 按钮。translatesautoresizingmaskintoconstraints = 假

  59. 按钮。heightanchor。约束(equaltoconstant:starsize。高度)。活跃 = 真正的

  60. 按钮。widthanchor。约束(equaltoconstant:starsize。宽度)。活跃 = 真正的

  61. / /设置按钮的动作

  62. 按钮。addtarget(自己,行动:#选择器(ratingcontrol。ratingbuttontapped(按钮:)),为:。touchupinside)

  63. //将按钮添加到堆栈

  64. addarrangedsubview(按钮)

  65. / /添加新的按钮,按钮阵列的评级

  66. ratingbuttons。追加(按钮)

  67. }

  68. updatebuttonselectionstates()

  69. }

检查点:运行你的应用程序。你应该看到五颗星星,可以点击一个改变评级。点击第三星级改变评级为3,例如。点击同一星一次。控制应复位到一零星评级。

添加辅助信息

iOS内置的辅助功能,您可以提供卓越的移动体验,为每一位客户,包括那些有特殊需要的。这些功能包括画外音、开关控制、播放音频或视频的图文描述,引导接入,语音,和更多。

在大多数情况下,用户受益于这些功能,而没有任何额外的工作。画外音,但是,往往需要注意一点。画外音在盲与低视力的用户一个革命性的屏幕阅读器。画外音读你的用户界面,用户。虽然内置控件默认的描述提供了一个很好的起点,你需要优化你的用户界面呈现尤其是自定义的视图和控件。

对于等级控制,你需要为每个按钮信息额外的三件,

  • 可达性标签。短的、本地化的词或短语,简明扼要的介绍了控制或视图,但不确定元素的类型。例如“添加”或“玩”。

  • 知识的价值。一个元素的当前值,当该值不被标签为代表。例如,一个滑块的标签可能是“速度,但其目前的价值可能是“50%”。

  • 可访问性暗示。一个简单的,局部的短语来描述元素的动作结果。的例子是“添加标题”或“打开购物清单。”

在分级控制,每个按钮的可达性标签说明按钮设置值。例如,第一个按钮的标签上写着“1星级”的可控制的电流额定值包含。例如,如果你有一个4星评级,价值说“4星集”。最后,你当前所选的明星说,分配一个暗示,“点击重置等级为零。“所有其他的明星有零值的暗示,因为他们的影响已经被充分地描述他们的标签。

添加可访问性标签,价值观,和提示

  1. 进入ratingcontrol.swift,浏览到setupbuttons()方法找到为—进入宣言.替换占位符循环变量(_)与指数如图所示:

  2. 为指数进入零..<StarCount{

  3. 里面的为—进入环,只是在约束,添加以下代码:

    此代码计算使用的按钮的索引标签的字符串,然后把它分配给按钮的accessibilitylabel财产

    这个setupbuttons()方法应该是这个样子的:

  4. 私人功能setupbuttons(){

  5. / /清除任何现有的按钮

  6. 为按钮进入ratingbuttons{

  7. removearrangedsubview(按钮)

  8. 按钮。removeFromSuperview()

  9. }

  10. ratingbuttons。移除所有()

  11. 按钮/ Load Images)

  12. 让束 = 束(为:类型(属于:自己))

  13. 让“filledstar” = UIImage(命名:“filledstar”,进入:束,兼容:自己。traitcollection)

  14. 让“emptystar” = UIImage(命名:“emptystar”,进入:束,兼容:自己。traitcollection)

  15. 让“highlightedstar” = UIImage(命名:“highlightedstar”,进入:束,兼容:自己。traitcollection)

  16. 为指数进入零..<StarCount{

  17. /“Create按钮

  18. 让按钮 = UIButton()

  19. 按钮/看Images)

  20. 按钮。西雅图(“emptystar”,为:。正常)

  21. 按钮。西雅图(“filledstar”,为:。挑选)

  22. 按钮。西雅图(“highlightedstar”,为:。突出)

  23. 按钮。西雅图(“highlightedstar”,为:[。突出,。挑选])

  24. / /添加约束

  25. 按钮。translatesautoresizingmaskintoconstraints = 假

  26. 按钮。heightanchor。约束(equaltoconstant:starsize。高度)。活跃 = 真正的

  27. 按钮。widthanchor。约束(equaltoconstant:starsize。宽度)。活跃 = 真正的

  28. //设置无障碍标签

  29. 按钮。accessibilitylabel = 星级评定”

  30. / /设置按钮的动作

  31. 按钮。addtarget(自己,行动:#选择器(ratingcontrol。ratingbuttontapped(按钮:)),为:。touchupinside)

  32. //将按钮添加到堆栈

  33. addarrangedsubview(按钮)

  34. / /添加新的按钮,按钮阵列的评级

  35. ratingbuttons。追加(按钮)

  36. }

  37. updatebuttonselectionstates()

  38. }

  39. //设置无障碍标签

  40. 按钮。accessibilitylabel = 星级评定”

  41. 导航到updatebuttonselectionstates()方法。里面的为—进入环,刚过线,设置按钮的添加以下代码选择财产

    在这里,你先检查按钮是否是当前选中的按钮。如果是,你分配一个暗示。如果不是,你将按钮的hintstring属性零。

    接下来,你计算的价值基于控制的评级。使用开关语句来指定自定义字符串如果评级是零或一。如果评级大于一使用字符串插值计算,你的暗示。

    最后,在分配这些值accessibilityhint和accessibilityvalue性能

  42. / /设置当前选定的明星提示字符串

  43. 让hintstring:字符串?

  44. 如果评级 == 指数一{

  45. hintstring = “点击重置等级为零。”

  46. }其他的{

  47. hintstring = 零

  48. }

  49. //计算值的字符串

  50. 让valuestring:字符串

  51. 开关(评级){

  52. 案例零:

  53. valuestring = “没有等级设置。”

  54. 案例一:

  55. valuestring = “1星集。”

  56. 默认:

  57. valuestring = 星星。”

  58. }

  59. //指定提示字符串和字符串值

  60. 按钮。accessibilityhint = hintstring

  61. 按钮。accessibilityvalue = valuestring

当用户运行应用程序时启用VoiceOver,触摸一个按钮,画外音读取按钮的标签,其次是词按钮。然后读性价值。最后,它读取访问的提示(如果有)。这让用户知道控制的当前价值和结果利用当前选中的按钮。

进一步探讨

关于可访问性的更多信息,参见可在iOS。

同时,对这节课的目的,给你简单的字符串的访问性能;然而,一个生产应用程序应该使用本地化的字符串。在国际化和本地化的更多信息,参见为世界建立应用程序。

连接等级控制视图控制器

你需要做的设置等级控制的最后一件事就是给视图班上的一个参考吧。

连接一个等级控制出口viewcontroller.swift

  1. 打开你的故事。

  2. 点击在Xcode工具栏按钮打开助理助理编辑。

  3. 如果你想要更多的工作空间,崩溃项目导航和实用面积通过点击导航和公用事业在Xcode工具栏按钮。

    你也可以折叠大纲视图。

  4. 选择等级控制。

    viewcontroller.swift displays in the editor on the right. (If it doesn’t, choose Automatic > ViewController.swift in the editor selector bar.)

  5. 控制拖动额定控制你的画布,在右边的编辑显示的代码,在线路下方的停止拖动photoimageview财产viewcontroller.swift。

  6. 在出现的对话框中,名称,类型ratingcontrol。

    把其余的选项有。你的对话应该是这样的:

  7. 单击“连接”。

这个视图类现在已经在故事情节中的等级控制的参考。

清理项目

你接近完成的吃饭场景的用户界面,但首先你需要做一些清理工作。现在,foodtracker程序实施更先进的行为比以前的经验教训,一个不同的用户界面,你将要删除你不需要的部分。你也会中心的元素在栈的观点来平衡用户界面。

清理界面

  1. 通过单击“标准按钮返回标准编辑。

    拓展项目导航和实用面积通过点击导航和公用事业在Xcode工具栏按钮。

  2. 打开你的故事。

  3. 选择设置默认的标签文本按钮,然后按Delete键删除它。

    堆栈视图将用户界面元素来填补缺口,按钮左。

  4. 如果有必要,打开大纲视图。选择堆栈视图对象。

  5. 打开属性检查

  6. 在属性检查器中,找到并选择中心对齐字段。

    堆栈中的视图的中心元素水平:

现在,删除与你删除按钮的操作方法。

清理代码

  1. 开放viewcontroller.swift。

  2. 进入viewcontroller.swift,删除setdefaultlabeltext(_:)动作方法。

    这就是所有你需要删除现在。你的标签出口做出改变(mealnamelabel在以后的课程)。

  3. @ IBAction功能setdefaultlabeltext(发件人:UIButton){

  4. mealnamelabel。文本 = “默认文本”

  5. }

检查点:运行你的应用程序。所有工作都应该一如既往,但设置默认的标签文本按钮消失了,和元素水平居中。按钮应并排。点击任何按钮,在这一点上还是要打ratingbuttontapped(_:)和按钮图像适当改变。

重要

如果你运行到建设问题,command-shift-k到试压清洁你的项目。

结束了第四篇

在本课中,您学习了如何建立一个自定义控件,可以显示在界面生成器。控制也暴露了,可以在属性检查器中的改性。最后,你添加的辅助功能信息,确保控制工程与画外音。

接下来,你将和连接的应用程序的数据模型设计。

定义你的数据模型(第五篇)

在本课中,您将定义和测试数据模型为foodtracker APP。数据模型是存储在一个应用程序的信息结构。

学习目标

at the end of the课程,你将能够:

  • 创建一个数据模型

  • 一个自定义的类写failable初始化

  • 展示了一个failable和nonfailable初始化的区别的概念的理解

  • 通过编写和运行单元测试的测试数据模型

创建一个数据模型

现在你可以创建一个数据模型来存储这顿饭的信息场景需要显示。这样做,你定义了一个简单的类一个名字,一张照片,和一个等级。

创建一个新的数据模型类

  1. 选择文件>新建>文件(或按了N命令)。

  2. 在出现的对话框的顶部,选择iOS。

  3. 选择快捷的文件,然后单击“下一步”。

    你用不同的方法来创建这个类的比ratingcontrol class you created earlier (iOS > Source > Cocoa Touch Class), because you’re defining a 基类你的数据模型,这意味着它不需要从其他类继承。

  4. 在保存领域,类型餐。

  5. 保存位置默认为你的项目目录。

    这组选项默认为您的应用程序的名字,FoodTracker。

    在目标部分,你的应用程序选择并为你的应用程序的测试选择。

  6. 离开这些默认设置它们,然后点击创建。

    Xcode创建一个文件名为meal.swift。在项目导航,拖动meal.swift其他文件下的文件快速和位置,如果必要的话。

迅速,可以用一个代表的名字字符串,使用照片UIImage,而评级使用int。因为吃饭都有一个名字和评级,但可能没有一张照片,使UIImage一个可选择的。

定义数据模型的一顿饭

  1. 如果助理编辑打开,点击标准按钮返回标准编辑。

  2. 开放meal.swift。

  3. 变化的import语句导入UIKit替代基础:

    当Xcode创建一个新的快速的文件,它进口的基础框架,默认情况下,让你在你的代码中的基础数据结构的工作。你也可以从UIKit框架一类的工作,所以你需要导入UIKit。然而,进口UIKit也给你访问的基础,这样你可以删除冗余的进口基础。

  4. 进口UIKit

  5. 下面的导入语句,添加以下代码:

    这段代码定义了需要存储的数据的基本性质。你把这些变量(VaR常数(instead of)让因为他们需要)在一个变化的过程餐对象的生命周期。

  6. 类餐{

  7. / /马克:性能

  8. VaR姓名:字符串

  9. VaR照片:UIImage?

  10. VaR评级:int

  11. }

  12. 下面的属性,添加此代码声明一个初始化:

    回想起初始化一类是准备用实例的方法,这涉及到每一个初始值设定财产和执行其他的安装或初始化。

  13. / /马克:初始化

  14. 初始化(姓名:字符串,照片:UIImage?,评级:int){

  15. }

  16. 填写基本实现通过设置属性等于参数值。

    但是如果你试图创建一个不正确的值饭会发生什么,就像一个空的名称或负面的评级?你需要返回零表示该项不能被创建,并已设置为默认值。你需要添加代码来检查这些案件并返回零如果他们失败了。

  17. //初始化存储性能。

  18. 自己。姓名 = 姓名

  19. 自己。照片 = 照片

  20. 自己。评级 = 评级

  21. 将下面的代码添加上面的代码,初始化存储性能。

    此代码验证传入的参数并返回零如果他们包含无效值。

    注意,编译器应该用一个错误陈述抱怨,“只有failable初始化可以返回无。”

  22. //初始化应该如果评级是负面的没有名字或失败。

  23. 如果姓名。栈空| |评级 < 零{

  24. 退货零

  25. }

  26. 单击错误图标调出修复它。

  27. 双击修复更新你的初始化。初始化的签名应该是这个样子的:

    failable初始化总是开始与初始化?或初始化!。这些初始化返回可选择的值或隐式打开可选值,分别。自选项目可以包含有效值或零。你必须看看可选的有价值,然后安全地打开值之前,你可以用它。隐式打开自选选项,但系统隐式地为你打开。

    在这种情况下,你的初始化返回一个可选饭?目标

  28. 初始化?(姓名:字符串,照片:UIImage?,评级:int){

在这一点上,你init ?( name: String , photo: UIImage ?, rating: Int )初始化看起来应该像这样:

  1. 初始化?(姓名:字符串,照片:UIImage?,评级:int){

  2. //初始化应该如果评级是负面的没有名字或失败。

  3. 如果姓名。栈空| |评级 < 零{

  4. 退货零

  5. }

  6. //初始化存储性能。

  7. 自己。姓名 = 姓名

  8. 自己。照片 = 照片

  9. 自己。评级 = 评级

  10. }

进一步探讨

你会看到,在以后的课程中,failable初始化器是更难使用,因为你需要打开返回的随意使用它之前。一些开发商宁愿执行初始化的合同中的应用assert()或预调整(的)方法.这些方法导致应用程序如果测试失败的情况下终止。这意味着调用代码必须调用初始化前验证输入。

在初始化列表的更多信息,参见初始化。有关添加内联检查及条件代码的信息,参见assert(_ _线:文件:::)和precondition(_::::_在线文件)。

检查点: Build your project by choosing Product > Build (or pressing Command-B). You’re not using your new class for anything yet, but building it gives the compiler a chance to verify that you haven’t made any typing mistakes. If you have, fix them by reading through the warnings or errors that the compiler provides, and then look back over the instructions in this lesson to make sure everything looks the way it’s described here.

测试你的数据

虽然你的数据模型的代码生成,你还没有完全纳入到你的应用程序呢。作为一个结果,告诉你是否已经实现的一切正确,这很难,如果你可能遇到的边缘情况,你没有考虑到在运行时。

要解决这种不确定性,你可以编写单元测试。单元测试用于测试小型、独立的代码,以确保他们正确的行为。这个餐类是单元测试的完美候选人。

Xcode已经创建了一个单元测试文件为单视图应用程序模板的一部分。

看foodtracker单元测试文件

  1. 打开foodtrackertests文件夹在项目浏览器中通过点击它旁边的三角形。

  2. 开放foodtrackertests.swift。

花一点时间来了解文件中的代码为止。

  1. 进口xctest

  2. @测试进口foodtracker

  3. 类foodtrackertests:xctestcase{

  4. 重写功能设置(){

  5. 超级的。设置()

  6. //把设置代码在这里。该方法在每个测试方法的类的调用调用。

  7. }

  8. 重写功能拆卸(){

  9. //把teardown代码在这里。该方法是在每个测试方法的类的调用后调用。

  10. 超级的。拆卸()

  11. }

  12. 功能testexample(){

  13. /这是一个功能测试案例。

  14. / /使用XCTAssert和相关的功能验证测试产生正确的结果。

  15. }

  16. 功能testperformanceexample(){

  17. /这是一个性能测试案例。

  18. 自己。测量{

  19. / /把你想要测量的时间,这里的代码。

  20. }

  21. }

  22. }

代码开始通过进口的xctest框架和应用程序。

注意代码的使用@测试当导入应用程序属性。这使您的测试访问内部元素的应用程序代码。记住,斯威夫特默认内部访问控制的所有类型,变量,属性,初始化,和功能的代码。如果你没有明确标示一项私人或私人文件,你可以从你的测试访问。

的xctest框架是Xcode的测试框架。单元测试本身是一个类定义,foodtrackertests,继承自xctestcase。the comments解释代码setup()和teardown()方法,以及两样本测试用例:testexample()和testperformanceexample()。

测试你可以写的主要类型是功能测试(检查一切生产价值你期望)和性能测试(检查你的代码执行的是你期待的那样快)。因为你没有写任何性能的重码,你只会想现在写功能测试。

测试用例的简单方法,系统自动运行你的单元测试的一部分。创建一个测试用例,创建一个方法的名称的词开始测试。最好给你的测试案例是描述性的名字。这些名字使它更容易识别的个人测试之后。例如,一个测试检查餐类的初始化代码可以被命名为testmealinitialization。

写餐对象初始化单元测试

  1. 进入foodtrackertests.swift,你不需要使用任何模板的存根方法本课。删除模板的方法。你的食物跟踪测试应该出现如下图所示:

  2. 进口xctest

  3. @测试进口foodtracker

  4. 类foodtrackertests:xctestcase{

  5. }

  6. 在最后的大括号(}),添加下面的:

    这是一个注释来帮助你(或任何人谁读你的代码)浏览您的测试和识别他们所对应的。

  7. / /马克:饭类测试

  8. 下面的评论,添加一个新的测试用例:

    系统自动运行测试用例,执行单元测试。

  9. / /确认餐饭时初始化返回一个对象通过有效参数。

  10. 功能testmealinitializationsucceeds(){

  11. }

  12. 添加测试,使用无等级和积极评价最高的测试用例。

    如果初始化工作如预期的那样,这些电话init(姓名,照片,评价:)要成功。xctassertnotnil验证了,通过检查返回的餐对象不是零。

  13. / /零评级

  14. 让zeroratingmeal = 餐。初始化(姓名:“零”,照片:零,评级:零)

  15. xctassertnotnil(zeroratingmeal)

  16. 阳性/最高评级

  17. 让positiveratingmeal = 餐。初始化(姓名:“积极”,照片:零,评级:五)

  18. xctassertnotnil(positiveratingmeal)

  19. 现在添加一个测试情况餐类的初始化失败。在添加下面的方法testmealinitializationsucceeds()方法

    再次,系统自动运行测试用例,执行单元测试。

  20. / /确认餐initialier返回时通过负面的评级或空名。

  21. 功能testmealinitializationfails(){

  22. }

  23. 现在添加测试的测试用例调用无效参数初始化。

    如果初始化工作如预期的那样,这些电话init(姓名,照片,评价:)失败。xctassertnil验证了通过检查返回的餐对象是零。

  24. / /负面评级

  25. 让negativeratingmeal = 餐。初始化(姓名:“负面”,照片:零,评级:- 1)

  26. xctassertnil(negativeratingmeal)

  27. / /空字符串

  28. 让emptystringmeal = 餐。初始化(姓名:“”,照片:零,评级:零)

  29. xctassertnil(emptystringmeal)

  30. 到目前为止,所有的试验成功。现在添加一个测试会失败。将下面的代码添加的负面评级和空字符串之间的测试:

  31. / /超过最大额定值

  32. 让largeratingmeal = 餐。初始化(姓名:“大”,照片:零,评级:六)

  33. xctassertnil(largeratingmeal)

你的单元测试类应该看起来像这样:

  1. 类foodtrackertests:xctestcase{

您可以添加额外的xctestcase subclasses to your FoodTrackerTests target to add additional test cases. Run all of your unit tests at the same time by choosing Product > Test (or pressing Command-U). You can also run an individual test.

检查点: Run your unit tests by selecting the Product > Test menu item. The testmealinitializationsucceeds()测试用例应该成功,而testmealinitializationfails()测试用例失败。

注意,Xcode自动打开测试导航仪的左侧,并强调考试不及格。

编辑器窗口中显示当前打开的文件的结果。在这种情况下,如果它的一个或多个测试方法测试失败。如果它的一个或多个测试失败,测试方法失败。在这个例子中,只有xctassertnil(largeratingmeal)实际测试失败。

测试导航也列出了单独的测试方法,通过测试用例分组。单击“测试方法在编辑器的代码导航。图标右边显示是否成功或失败的试验方法。你可以重新运行测试方法的移动鼠标的成功或失败的图标。当它变成一个游戏的箭头图标,点击它。

正如你看到的,单元测试帮助捕获代码中的错误。他们还帮助定义你的类的预期行为。在这种情况下,如果你通过一个空字符串或负面评级的粕类的初始化失败,但不失败,如果你通过一个等级大于5。回去修理。

修复错误

  1. 进入meal.swift,找到初始化?(姓名,照片,评价:)方法

  2. 您可以修改如果条款,但复杂的布尔表达式变得难以理解。相反,取而代之的是一系列的检查。此外,因为你是让代码执行之前的数据验证,使用警卫声明.

    一警卫语句声明了一个条件,必须是真的为了代码后警卫statement to be执行。如果条件是假,的警卫声明的其他的退出当前代码块分支必须(例如,通过调用退货,打破,持续,抛出,或方法不返回一样致命错误(_线:文件::))。

    替换此代码:

    with the following:

  3. / /名称必须不让空

  4. 警卫!姓名。栈空其他的{

  5. 退货零

  6. }

  7. / /评级必须在0和5范围

  8. 警卫(评级 >= 零) && (评级 <= 五)其他的{

  9. 退货零

  10. }

  11. //初始化应该如果评级是负面的没有名字或失败。

  12. 如果姓名。栈空| |评级 < 零{

  13. 退货零

  14. }

你的初始化?(姓名,照片,评价:)方法应该是这样的:

  1. 初始化?(姓名:字符串,照片:UIImage?,评级:int){

  2. / /名称必须不让空

  3. 警卫!姓名。栈空其他的{

  4. 退货零

  5. }

  6. / /评级必须在0和5范围

  7. 警卫(评级 >= 零) && (评级 <= 五)其他的{

  8. 退货零

  9. }

  10. //初始化存储性能。

  11. 自己。姓名 = 姓名

  12. 自己。照片 = 照片

  13. 自己。评级 = 评级

  14. }

检查点:你的应用程序运行你写单元测试。所有的测试用例应该通过。

单元测试是写代码的必不可少的一部分,因为它可以帮助你发现错误,你可能忽略。正如他们的名字所隐含的,让单元测试的模块化是很重要的。每个测试应该检查一个特定的行为的基本类型。如果你写单元测试,是长的或复杂的,它会更难追查到底出了什么问题。

结束了第五篇

在本课中,你建立了一个模型类来保存您的应用程序的数据。你也failable定期检修的初始化和初始化的区别。最后,你说了几个单元测试来帮助您查找和修复代码中的错误。

在以后的课程中,你将在你的应用程序的代码中使用对象模型来创建和管理膳食清单。然而,在你做之前,你需要学习如何显示一个列表的使用表格视图的饭菜。

那么构建用户界面这篇大大的文章就到这里全部结束了。如喜欢请关注我的文章,如有问题请联系(购买咨询 Q Q :220535700)iOS打包、苹果企业证书、出售、签名、申请、技术咨询、开发!


评论
热度(2)