006 添加余下的控件并讲什么是 String

作者: ErlichLiu | 来源:发表于2017-09-25 13:27 被阅读11次

上一节

你的 App 已经有了一个按钮了,你还需要把剩下的 UI 控件添加进去就可以了。这是注释过的 UI 控件和布局样式。

正如你所见,我在一些 Label 的值上用了占位符,这样可以让你更轻松地找到某个位置是有一个 Label 的,当你真的开始使用的时候,你可以用真实的值来填充。

尝试重新从控件库中拖拽控件,重新排布屏幕的设计。你需要一些新的按钮,标签和滑块控件。你可以在屏幕截图中对控件的大小和排布略知。

下面要做的就是用 Attribute inspector 来调整这些控件,在 Xcode 窗口的右边,你会发现图片上的 inspector。

Attribute inspector 会显式当前选中项目的很多属性。比如修改按钮的背景颜色,文字的大小啊等等。所以也相信你已经发现了 inspector 和所选项目各种属性之间的联系了。当你开始娴熟的使用 Xcode 的时候,你会用到 Attribute inspector 来修改你的设计视图。

我们先来修改那个在图片上看上去像是一个 ( i ) 的按钮,选中这个按钮,然后找到 Attribute inspector ,在 Type (类型) 一栏选择 Info Light ,当你回去再看这个按钮的时候它就已经变成跟图片上的一模一样啦。

同样使用 Attribute inspector 来修改 slider ,它的最小值应该是1,最大值应该是100,并且当前值因该是50。

但你都设置完毕,在你的视野里应该有12个控件:一个滑块,三个按钮,剩下一堆是标签 (Label),完美。

你可以运行 App 试一下啦,虽然除了 Hit Me 按钮外就没什么响应了,但是至少 slider 还是可以滑动的。

现在继续在你的 TODO list 上划掉几项吧,虽然刚刚的这些操作都没有涉及到代码,但是我们马上就要开始写代码啦。

Slider


你的下一项 TODO list 是:在点击 Hit Me 按钮后读取滑块的值。

如果你没有意外的断开与 showAlert 的连接,就可以直接在弹出窗口的提示消息中显示数值,如果不小心断开了与 showAlert 的连接,你需要重新连接上(hook it up)。

还记得当你想响应按钮操作时候在 view controller 里添加代码的方式吗?如果想读取滑块控件的值一样需要这样的操作。

  • 首先还是到 ViewController.swift 中,然后在最后一个花括号之前添加一下代码。
@IBAction func sliderMoved(_ slider: UISlider) { print("The value of the slider is now: \(slider.value)") }
  • 然后跳转到 storyboard ,按住 Ctrl 并拖拽滑块控件到Outline 面板的 View Controller(那个黄色的像是方孔圆币的图标)。松开鼠标后在弹出的选项里选择 sliderMoved。完毕!

在 Outline 面板有个白色的图标只叫 View 的层级,这个层级包含了所有你添加的控件。

记住:如果找到不到 Outline 面板,请在左下角找到这个小图标,然后点击它。

当你操作完,sliderMoved() 方法就已经和滑块的值挂钩了。这也就意味着每当你向左或者向右滑动滑块的时候,都会调用这个方法。

你可以在 Connection inspector 里核对一下是是否连接到了 sliderMoved() 。

注意:
你是否注意到了 showAlert() 方法和 sliderMoved() 方法不完全一样呢?后者有一个参数 slider,但是 showAlert() 就没有。不用担心,你很快就会接触到关于参数的问题了。

现在你可以运行一下 App ,当你拖动滑块控件的时候,会在 Debug area 看到以下类型的数据。

如果你一直向左拖动滑块,你会发现数值会降到1;反之数值会上升到100。

print() 方法是为了帮助显示在 App 里都发生了什么事,在当前方法中,它的整个使命就是在 Debug area 打印出信息,这里主要是验证你的 slider 控件是否成功和 sliderMoved() 绑定。为了在做更多修改之前快速验证当前步骤的正确性,采用 print() 是一个不错的方法。

你可能已经注意到在 Debug area 有一大堆其他的消息,这个输出是从 iOS 模拟器和 UIKit 的信息输出,当前你可以简单的忽视他们。

字符串


当你想在你的 App 上显示一些文本信息,那么你会用到叫做 string 的数据结构,而且你会用很长时间。string 就是字符串,短期内你可以忽略掉数据结构这个字眼。

"Hello, World"
"This is my first app!"
"Awesome"
"The value of the slider is now: \(slider.value)"

前三个字符串都会被用于 UIAlertController,最后一个就是刚刚你用来 print() 方法中显式出来的值。

字符串(string)就是一堆文本被排列成一个队列,所以形象的称之为字符串。

以下的图片,这大概就是对字符串最形象的解释了。

字符串在你编写 App 的时候几乎无处不在,所以当你完成本套教程,你就会对使用字符串有很多的经验了。

创建一个字符串只需要将文字放在两个双引号下(英文状态下哦), 在其他一些语言环境下你也可以把文字放在单引号下(同样是英文状态下的哦),但是在 Swift 语言里一定要用双引号。

// 这是正确的字符串:
 "I am a good string"

// 以下皆错:
'I should have double quotes' 
''Two single quotes do not make a double quote'' 
“My quotes are too fancy” 
@"I am an Objective-C string"

print() 语句中也是使用字符串,在这句里The value of the slider is now: \(slider.value)\(...)这个其实就是一个占位符,你可以这样来理解这段话The value of the slider is now: X,现在的X就是滑块的值(即slider.value)。这种填充括号中的值的做法在 Swift 中非常常见。

介绍变量


通过使用print()函数在 App 中打印出即时的信息来Debug 是非常实用的做法,但是对用户而言一点用都没有,因为用户根本看不到这些。

所以让我们来做些改动,通过弹出的消息提示框来告知用户这些信息吧。那么我们面临的问题就是怎么在 showAlert()中获得 slider 的值?

当你在sliderMoved()方法中读取到值后随着方法的执行完毕,这个值也就转瞬即逝了如果有个东西可以帮我们将这个数据保存到用于点击 Hit Me 按钮的时候就好了。

幸运的是 Swift 有考虑到这一点,那就是可以存储数据的——变量。

  • 首先打开 ViewController.swift ,然后将下面的代码添加到 ViewController 类的顶部。
var currentValue: Int = 0 

在整个代码里看起来是这样的,现在你已经添加了一个叫做 currentValue 的变量到 ViewController 对象中了。

import UIKit class ViewController: UIViewController {

var currentValue: Int = 0 override func viewDidLoad() {

. . .

} override func didReceiveMemoryWarning() {

. . .

} @IBAction func showAlert() {

. . .

} @IBAction func sliderMoved(_ slider: UISlider) {

. . . }

}

第一个方法上面那行代码是自定义的变量。在开始一句新的代码或者一段新的代码的时候,都要缩进,有些人喜欢按两个空格键有的喜欢按一个tab键。这是一个个人爱好的问题啦,你可以在偏好设置里选择设置。在 Xcode 的菜单栏选择 XcodePerferencesText EditingIndentation tab

还记得我当时说 view controller 或者其他对象一般都会同时具有功能和数据吗? 现在变量就是我所说的数据的一部分。

变量赋予了 App 可以记住一些数据的能力,可以把变量想象成为一个暂时存储数据的容器。并非把数据存在变量里后就什么都不管了,通常使用变量就是因为这个数据会经常变换,所以你经常会用更新的数据来替换这些老的数值。你需要记住变量最重要的点就是可变性。

应用到当前 App 中的情况就是,你需要在滑块一有变动的时候就要记录下当前的值,这时候你可以把当前读取到的滑块的值不断地赋值给变量。

在本例中你指定了 currentValue 的类型为 Int(整数型),这样就意味着可以充当容器的变量可以存储整数型的数据。Int 是众多类型中常见的类型之一,你甚至可以创建你定制的类型。

变量就像是儿童的玩具块:

游戏规则就是将正确的形状放进正确的容器里,容器就是变量,容器最初的形状取决于你最初的定义,等待放进去的形状就是数据了,每种不同形状的图形就是一种数据类型。

变量是一个暂时存储的容器,那么它能存储多多长时间的数据?理论上来说它可以永久的存储直到你在变量里存储下一个数据或者一并销毁这些容器。

但是每个变量都有一个明确的生命周期,这要取决于你的程序是什么时候定义的变量。在当前的例子中,currentValue 变量的生命周期是和 view controller 对象的生命周期捆绑在一起的。即当 view controller 存在变量就存在,view controller 被销毁,变量就被销毁。

也就是说在 App 的进程没有被杀死之前,变量都是存在的,这也就是 currentValue 的生命周期。很快你就会看到生命周期短的多的本地变量。

理论部分就先到此结束,开始写代码让变量为我所用。

  • ViewController.swift 中修改 sliderMoved() 方法如下所示:
@IBAction func sliderMoved(_ slider: UISlider) { currentValue = lroundf(slider.value) }

相对于之前的变化而言,你用下面的语句替换掉了 print()语句。

currentValue = lroundf(slider.value)

在代码上这能显示出什么变化呢?在这之前,是可以直接通过print()的方法将实时的 slider 的值显示出来,现在同样要通过slider.value来实时读取 slider 的值,这个值其实并不止是 1 到 100 的整数,可能在小数点背后还有两位数。相较于currentValue的值,则是你刚刚创建的变量。当你想把新的值赋值给变量,你需要这样做:

变量 = 新的值

这个过程就称之为是赋值,这就相当于把图形放到盒子里,现在你只需要用真实的代码代替图形和盒子就可以啦。

lround又是什么呢?因为刚刚解释说 slider 的数值在小数点后还有两位数的小数,在你用print()函数打印出当前 slider 的值的时候,你肯定已经关注到数值后面是有两位小数的。所以让玩家猜测从 1 到 100 的整数就够难的了,要是让用户猜测整数位后面的两位小数就实在太难了。所以这就是为何要定义currentValue 是 Int(整数)类型了。在整数后面有两位小数就是 decimal 类型了,不同类型的数据是不能直接赋值的,但是因为 decimal 的精度更高,可以从高精度降低到低精度的数字,所以我们用lround()方法来降低 slider 值的精度,让这个数值可以变成 Int 类型。

  • 现在来修改 showAlert() 方法
@IBAction func showAlert() {

let message = "The value of the slider is: \(currentValue)" 
let alert = UIAlertController(title: "Hello, World", message: message, preferredStyle: .alert) 

let action = UIAlertAction(title: "OK", 
style: .default, handler: nil) 

alert.addAction(action) 
present(alert, animated: true, completion: nil)

}

与之前版本的 showAlert() 比起来,带有 let message = ... 的这一行是新增的,另外还有两个小的变化。

像之前一样,你创建并显示了 UIAlertController,当你点击按钮的时候会显示「The value of the slidre is:X」,现在需要用currentValue来替换掉 X 。

至于前面用到的print()函数,那个只是显示在 Debug 栏里,并不会显示给用户看,所以怎么处置都没什么大关系。

  • 你可以重新运行 App 啦,拖动滑块,然后点击按钮,看看你拖动滑块位置的数值吧。

Cool!你现在已经成功使用变量来存储数据,并且也接触到了 Int 这种数据类型。

回顾一下本节的内容吧,下一节我们将找到你可能遇到的第一个 bug 以及我们是如何解决它的。

下一节

相关文章

网友评论

    本文标题:006 添加余下的控件并讲什么是 String

    本文链接:https://www.haomeiwen.com/subject/jlarextx.html