[译] 零基础 macOS 应用开发(二)
本文翻译自 raywenderlich.com 的 macOS 开发经典入门教程 ,翻译它只是因为宿舍太吵太热,只有这样才能一句一句看完,并作为自己的笔记,希望各位有英语阅读能力的话,还是去阅读英文原吧,毕竟无论是 Xcode,抑或是官方的文档,还是各种最前沿的资讯都只有英文版本。
综上,此翻译版本仅供参考,谢绝转载。相关链接
零基础 macOS 应用开发(一): 原文 / 译文
零基础 macOS 应用开发(二): 原文 / 译文(本文)
零基础 macOS 应用开发(三): 原文 / 译文(翻译中)
欢迎回到我们的零基础 macOS 应用开发教程的第二部分(共三部分)!
在第一部分,你了解了如何安装 Xcode、如何创建一个新的 app、添加 UI、连接代码与 UI、运行 app、调试 app,以及寻求帮助。如果你对上述内容还有任何不确定之处,再回去浏览一遍第一部分吧。
在这一部分,你将会创建一个界面更加复杂的 app。你将会学到如何应对可调整大小的窗口,以及设计第二个页面——偏好设置页面,并让你的 app 能跳转到这个新创建的页面。
准备开始
和第一部分一样,打开 Xcode 并在欢迎页面点击 Create a new Xcode project,或选择 File 菜单中的 New Project…。接下来在 macOS 下的 Application 标签页中选择 Cocoa Application,并点击 Next,把你的 app 命名为 EggTimer,确保 Language 选项为 Swift 以及 Use Storyboards 被选中。点击 Next 然后找一个合适的地方存储这个项目。
编译并运行你的 app 来确保一切正常。
EggTimer App
你将会开发的 app 叫做 EggTimer,它能帮助用户倒计时,并显示剩余的时间。App 的界面上会有一个鸡蛋的图标,随着时间的临近,鸡蛋会被慢慢煮熟;当你的鸡蛋煮熟时,还会有一个提示音。App 内还有一个页面会显示此 app 的偏好设置。
在 Project Navigator(项目导航器)中打开 Main.storyboard,正如第一部分所说的,你已经拥有了三个场景:
- Application Scene(应用场景)包含了只要 app 运行着就会显示的菜单栏。
- Window Controller(窗口控制器)是定义了 app 窗口有怎样行为(怎么调整大小、窗口怎么出现、app 是否会记住上次调整的大小和位置等等)的部分;其实一个 Window Controller 可以管理多个窗口,但如果它们的属性不同,你就需要多个 Windows Controller 了。
- View Controller 则显示了窗口中的用户界面——也就是你对 UI 进行布局的地方。
你注意到了吗?有一个箭头指向了 Window Controller,这表明它是 app 启动时的 initial display(初始页面)。你可以在 Document Outline(文档大纲)中选择 Window Controller,然后在 Attributes Inspector(属性检查器)中查看这个设置。取消勾选 Is Initial Controller(用作首要控制器)后,箭头就消失了。因为你需要它来作为首要的控制器,请把这个选项勾选上。
Window Controller(窗口控制器)
在你开始着手 UI 前,请确保你已经在 Project Navigator(项目导航器)中选择了 Main.storyboard。点击来选择其中的 window(窗口)。在可视化编辑器中,Window Controller显示了「View Controller」这行字,因为它包含着一个 View Controller(视图控制器)。在这个 app 中,我们不希望用户将窗口调整到 346 × 471 像素以下,这两个数值也将会是 app 启动时窗口的默认大小。
在 Utilities(工具集)面板中前往 Size Inspector(尺寸检查器),设置 Content Size Width(内容宽度)和 Content Size Height(内容高度)分别为 346;勾选 Minimum Content Size(最小内容尺寸)的复选框,并确保其数值与内容尺寸相同。现在,在可视化编辑器里的 Window Controller 的尺寸应该已经发生了变化,因此可能会盖住其他元素,你可能需要重新排列一下它们。
虽然不是必须的,但当你把 View Controller 和承放它的 Window Controller 调整到一样的大小后,后续操作会直观很多。点击并选中 View Controller,在 Size Inspector(尺寸检查器)中设置 Width 和 Height 分别为 346 和 471。如果需要的话,重新排列一下界面上的各个元素防止它们重叠。现在可视化编辑器里的 Window Controller 和 View Controller 都有着一样的尺寸了。
选中 WindowController 里的 Window,在 Attributes Inspector(属性检查器)中把它的名字更改为 Egg Timer,设置 Autosave name 为 EggTimerMainWindow,这样用户上次调整的窗口的尺寸和大小在 app 下次启动时就都会被记住了。
如果你是一个 iOS 开发者,你应该已经处理过不同设备、屏幕尺寸、屏幕旋转方向下的适配问题了。在 macOS 开发过程中,你必须处理无限多种窗口尺寸和长宽比,因此我在这里把窗口的默认尺寸调整成了这么一个奇怪的数字。不过好消息是,Auto Layout 帮助你解决了这个问题。
布局 UI(一)
基本的 UI 包含了两个 Stack View(堆叠视图):第一部分包含显示剩余时间的 Label 和鸡蛋的图标。第二个则在底部包含三个按钮,我们先来制作按钮:
- 在 Object Library(控件库)中搜索「Button」
- 向 View Controller 中拖动一个 Gradient button
- 使用 Attributes Inspector(属性检查器)删除它的图像,并把它 Title 设置为 Start
- 把字体改成 System 24
- 把按钮拖大一些让文字能显示完全
- 选中 Start 按钮,按下 Command⌘ + D 两次来复制两份
- 把新复制的按钮向右拖动一些,并把他们的 Title 改成 Stop 和 Reset
- 同时选中三个按钮,然后点击菜单栏上的 Editor → Embed In → Stack View
为了让按钮填满整个 Stack View,选择新创建的 Stack View,然后在 Attributes Inspector(属性检查器)里做出如下更改:
- Distribution(分配): Fill Equally(均分填满)
- Spacing(间距): 0
在可视化编辑器的底部点击 Add New Constraints(添加新的约束条件),设置左边、右边、底部和高度如上图所示。将 Update Frames 设置为 Items of New Constraints,然后点击 Apply 4 Constraints(应用四条约束)。
Stack View 现在已经放置好了,但这些按钮似乎比 Stack View 矮了一些,在 Document Outline(文档大纲) 中,按住 Control⌃ 键的同时拖动 Start 按钮到 Stack View 上,并选择 Equal Heights(高度等同)。对另外两个按钮进行同样的操作。
现在,包含了按钮的 Stack View 已经完全是我们想要的样子了。
编译并运行你的 app,尝试着改变窗口的大小,这些按钮会紧紧地贴在窗口的底部,并自动填满整个窗口的宽度。
最后一步,在 Attributes Inspector(属性检查器)中取消选中 Enabled 来禁用 Stop 按钮和 Reset 按钮,在计时开始前,这两个按钮不应该被启用。
布局 UI(二)
第二个 Stack View 包含剩余的时间以及鸡蛋的图片。向 View Controller 拖入一个 Label,把它的 Title(标题)设置为 6:00 并把 Alignment(对齐)设置为 center(居中)。默认的字体(San Francisco)会自动调整字符的间距——这意味着:随着倒计时的时间的变化,数字会来回跳跃——这会很烦人。
把字体改成 Helvetica Neue 来避免这样,然后把 Size(字体大小)设置为 100。这会使文字超出 Label 的范围,所以调整 Label 的大小直到你可以看到完整的文字。
现在我们需要添加一张图片,在 Object Library(控件库)的搜索框中输入「image」,这会过滤出很多长得很像的控件,你需要的是 Image View,将它拖动到 View Controller 中剩余时间 Label 的下方。
下载这个工程需要的资源文件(一些图片和一个声音文件),解压碎并打开 Egg Images 文件夹。回到 Xcode,在 Project Navigator(项目导航器)中点击 Assets.xcassets。
把这六个图片拖动到 Assets Library(资产库)中,然后它们就可以在你的 app 中使用了。因为图片的文件名中带有「@2x」,它们会被自动分配到各个图像资产的 @2x 区域。
关于 @2x 请自行搜索 Mac/iOS 的 HiDPI适应,译者注
前往 Main.storyboard,选中你刚刚添加的 Image View,在 Attributes Inspector(属性检查器)中点击 Image(图像)下拉框,在这个下拉框中你可以看到很多内置的图片以及你刚刚添加的图片,选中 stopped。
现在我们来制作第二个 Stack View:选中显示剩余时间的 Label 和刚刚调整好的 Image View,在菜单栏上点击 Editor → Embed In → Stack View。然后我们来调整一下这个 Stack View,使它填满剩余的空间。点击可视化编辑器底部的 Add New Constrains(添加新的约束),然后添加下图所示的约束条件:
正我们所需要的,Stack View 填满了剩下的空间,但这个 Image View 太小了,选中它,将它左右两您的约束按照下图设置为 User Standard Value(使用标准值):
在 Attributes Inspector(属性检查器)中,设置 Scaling(缩放) 为 Proportionally Up or Down(等比放大或缩小)。
编译并运行 app,调整窗口的大小,看看 UI 元素是否如预期地自动地适应了窗口尺寸。
连接 UI 和代码
在第一部分中,你已经知道了你需要使用 @IBOutlets
和 @IBActions
来连接你的 UI 和代码。在这个例子中,你需要为以下元素设置 @IBOutlets
:
- 剩余时间的 Label
- 显示鸡蛋的 Image View
- 三个按钮
此外,这三个按钮还需要@IBAction
来响应用户的点击操作。在 Project Navigator(项目导航器)中,先选中 Main.storyboard,再按住 Option⌥,点击 ViewController.swift,这样就可以在 Assistant Editor(辅助编辑器,即左右分栏)中打开它了。如果你的屏幕空间不足,点击右上角的按钮来隐藏 Utilities(工具集) 和 Navigator(导航器) 面板。
和第一部分一样,选中剩余时间的 Label,按住 Control⌃ 键的同时拖动它到 ViewController
类中,将名称设置为 timeLeftField
,对鸡蛋的 Image View 进行一样的操作,它的名字设置为 eggImageView
。然后是三个按钮,他们的名字分别设置成 startButton
、stopButton
和 resetButton
。
这三个按钮还需要 @IBAction
,按住 Control⌃ 并拖动 Start 按钮到代码中,但这次在弹出窗口中将 Connection 设置为 Action,并把它的名字设置为 startButtonClicked
,对另外两个按钮重复以上动作,为它们添加名为 stopButtonClicked
和 resetButtonClicked
的 @IBAction。
如果你和我一样也经常忘了把 Connection 修改为 Action 的话,你会得到 @IBOutlets
而不是 @IBAction
,如果你要删除这些多余的 @IBOutlet
,先把这一行代码删除,再转到 Utilities(工具集)里的 Connections Inspector(连接检查器),你会看到 Referencing Outlets 部分里有两个项目,点击错误连接旁的 × 来删除它,然后重新连接你的 @IBAction
(这一次别忘了修改 Action 哦 原文链接:https://www.f2er.com/swift/321124.html