IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> SwiftUI实战教程 第二章 BMI计算器 -> 正文阅读

[移动开发]SwiftUI实战教程 第二章 BMI计算器

代码库

教程中的项目代码都保存在这里:

https://github.com/NDFour/swiftui01

前言

在这一章里,我们会做一个BMI计算器,进一步加深我们在之前的章节里学习到的知识。这一章里我们会使用TextField用来获取用户的输入内容。

MBI指数用来帮你判断自己的体重是否超标,计算方法如下:

使用体重(单位:千克)除以身高(单位:米)的平方。

如:你的身高 175cm,体重70kg,那么BMI指数就是

70/1.75/1.75=22.9

BMI指数分级:

过轻:BMI < 18.5

正常:18.5 <= BMI <= 24.9

超重:25 <= BMI <= 29.9

肥胖:BMI >= 30

开始

新建项目

在第一章中我们介绍了如何使用 Xcode新建一个项目,如果忘记了可以回到第一章再复习一下。

新建好的项目长这个样子:
请添加图片描述

开始界面

ContentView.swift中我们添加了两个TextField用来输入体重和身高。当你需要获取用户的输入时都可以使用TextField

同时,我们还添加了一个Text用来显示BMI计算器

上面这些元素我们都放到一个VStack中。

struct ContentView: View {
    @State private var weightText: String = ""
    @State private var heightText: String = ""
    
    var body: some View {
        VStack {
            Text("BMI计算器").font(.largeTitle)
            TextField("体重(kg)", text: $weightText)
                .textFieldStyle(RoundedBorderTextFieldStyle())
            
            TextField("身高(m)", text: $heightText)
                .textFieldStyle(RoundedBorderTextFieldStyle())
            .border(Color.black)
        }.padding()
    }
}

TextField的第一个参数是一个提示用户输入内容的占位符,第二个参数绑定了我们一开始声明的两个参数:weightText, heightText
请添加图片描述
注意:我们在绑定自定义变量到TextField时在变量名前加了个$符号。

至此,当用户在TextField输入框中输入内容时,我们绑定的@State变量的值也会同步更新,换句话说,当@State变量的值发生变化时,TextField的内容同样也会改变。

我们为TextField添加了几个modifier,你可以删掉他们然后重新运行看看会产生什么结果。

假如你删除.border那么TextField将不会存在明显的边框,这回让用户难以区分输入框边界究竟在哪里。

textFieldStyle (RoundedBorderTextFieldStyle())则会让TextField产生圆角效果。

有了这些modifier我们就可以按照自己的喜好来展示不同风格的TextField(或者其他的 View)。

计算和输出按钮

接下来,我们要在界面上添加一个 计算BMI 按钮。

@State private var weightText: String = ""
@State private var heightText: String = ""
@State private var bmi: Double = 0

var body: some View {
    VStack {
        ...
        Button(action: {
            let weight = Double(self.weightText)!
            let height = Double(self.heightText)!
            self.bmi = weight/(height * height)
        }) {
            Text("计算BMI")
            	.padding()
            	.foregroundColor(.white)
            	.background(Color.blue)
        }
        
        Text("BMI: \(bmi)").font(.title).padding()
    }.padding()
}

在上面的代码中,我们将用户输入的内容赋值给weightheight。同时我们将其从 String 类型转换到了 Double 类型,因为我们要使用这两个值参与数学运算。

你可能会对代码后面的!产生疑问,先别着急,我会在后面的可选值部分中详细介绍。

在按钮下方我们添加了一个Text标签,用于展示计算出的 BMI 的值,我们在声明变量bmi时为其加上了@State,这样当 bmi 的值发生变化时,Text标签就会及时更新自己显示的内容。

运行

请添加图片描述
当你运行app并且输入身高体重后,点击计算 BMI按钮,你将会得到你的 BMI 计算结果。

但现在的计算结果小数点之后的部分太长()了,我们来格式化一下输出内容。

下面我们使用代码规定只展示小数点后1位数字:

Text(“BMI: (bmi, specifier: “%.1f”)”).font(.title).padding()

specifier用于字符串插值格式化,%.1f表示只保留浮点数小数点后1位数字。
请添加图片描述

BMI分级

接下来让我们为app添加BMI分级的功能,比如:

BMI:29.4,超重

我们需要在app中实现以下逻辑:

过轻: bmi < 18.5

健康:18.5 <= bmi <= 24.9

超重:25 <= bmi <= 29.9

肥胖:bmi >= 30

添加以下代码:

struct ContentView: View {
  	...
    @State private var classification: String = ""

    var body: some View {
        VStack {
            ...
            Button(action: {
                let weight = Double(self.weightText)!
                let height = Double(self.heightText)!
                self.bmi = weight/(height * height)
                
                if self.bmi < 18.5 {
                    self.classification = "过轻"
                } else if self.bmi < 24.9 {
                    self.classification = "健康"
                } else if self.bmi < 29.9 {
                    self.classification = "超重"
                } else {
                    self.classification = "肥胖"
                }
            }) {
                Text("计算BMI")
                    .padding()
                    .foregroundColor(.white)
                    .background(Color.blue)
            }

            Text("BMI: \(bmi, specifier: "%.1f"), \(classification)").font(.title).padding()
        }.padding()
    }`
}

我们通过声明一个@State变量calssification来存储计算后的 BMI 分级。

然后通过一系列的 if else语句来判断计算出的 bmi 所属的等级。

最后通过字符串插值的方式将classification展示到Text上。
请添加图片描述

可选值 Optionals

在上面的代码中,我们有这样的两行:

let weight = Double(self.weightText)!
let height = Double(self.heightText)!

为什么要在最后添加一个感叹号呢?如果你尝试着删除感叹号,Xcode 将会对下面这行代码报错:

self.bmi = weight/(height * height)

请添加图片描述

这是因为Double(<String>)实际上返回的是Double?,也就是可选的Double。对于任何变量来说,如果变量名后面加上了?,这就会将此变量看作optional类型(也就是可选的类型),这样的话这个变量要么有值,要么= nil。

举个栗子:

Double? 包含一个 Double 类型的值或者 nil

Int? 包含一个 Int 类型的值或者 nil

你可能还会有疑问,为什么Double(self.weightText)会返回一个可选的类型呢?他不应该返回一个 Double 类型么??

假如用户在输入框中输入的不是自己的身高体重,而是一个字符串,比如输入你好,swift零一,显而易见代码可没法把这个字符串转换成一个 Double !!

当用户输入的值没法按照预期目标转换为一个 Double 类型的数字时,就会返回一个 nil。

所以Double(self.weightText)将会返回一个可选的类型,如果用户输入的值是数字,将会成功被转换成 Double 类型返回,如果用户没有输入内容或者输入的内容无法转换成 Double 类型时就会返回 nil。

当我们要取一个optional类型变量的值时,需要在变量名后面加!

聪明的你应该想到了吧??这可是一个非常危险的操作!!

当一个optional变量的值为nil时,我们使用!来取值的话代码就会崩溃!

你可以尝试运行 BMI计算器 app不要输入任何内容直接点击计算,app会崩溃然后报错如下:

Fatal error: Unexpecteddly found nil while unwrapping an Optional value.

为了避免optiona的值为nil时通过!取值导致app崩溃,我们应该使用if let t语法。if let首先会检查optional变量是否包含一个不为nil的值,然后将该值绑定到一个临时变量。换句话说,这是==解包(取optional类型变量的值)==可选值的一个安全操作。

修改后的代码如下:

Button(action: {
    var weight: Double = 0
    var height: Double = 0
    
    if let weightDouble = Double(self.weightText) {
        weight = weightDouble
    }
    if let heightDouble = Double(self.heightText) {
        height = heightDouble
    } 
    ...
})

在上面的代码中,只有 Double(self.weightText)不为 nil 时代码才会进入 if 里,并把self.weightText转换为 Double 类型后的值赋给临时变量 weightDouble。当 Double(self.weightText) 为 nil 时代码不进入 if 循环,直接往下执行。

在黑暗模式下预览项目

至今为止,我们都是在默认的明亮模式下预览项目,Swift UI还支持在黑暗模式(Dark mode)下预览项目。

运行时使用黑暗模式

app在模拟器中运行时,你可以前往模拟器的Settings => Developer,然后打开Dark Appearance选项。

然后你的模拟器就会切换到黑暗模式,你的app也会自动切换到黑暗模式。

写代码时使用黑暗模式

为了在你写代码时预览在黑暗模式下的效果,你可以在preview代码段中田间environment修饰符。

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView().environment(\.colorScheme, .dark)
    }
}

在暗黑模式下,Text控件的字体会变为白色,但是背景依旧还是白色(在模拟器或者真机上不会存在这个问题)。可以将ContentView放到ZStack中然后设置背景色为黑色来解决这个小问题。

static var previews: some View {
    ZStack {
        Color(.black)
        ContentView().environment(\.colorScheme, .dark)
    }
}

小结

在这一章节中,我们通过使用Text, Button等控件学习了Swift UI的基本代码结构,我们学会了如何使用TextField获取用户的输入,还学会了如何为按钮增加点击事件。在这一过程中,我们完成了很有使用价值的一款app BMI计算器

在下一章节中,我将会带你学习List控件的使用。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-12-26 22:18:57  更:2021-12-26 22:20:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:23:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码