轻学编程|Swift 教程 014:存钱罐
轻学编程|Swift 教程 014:存钱罐

轻学编程|Swift 教程 014:存钱罐

本节课,我们将开发一个简单的“存钱罐”项目,功能简单,包含完整的交互逻辑,非常适合初学者入门。

通过这个项目,我们将学习 TextField(输入框)和 border 边框,并了解数据绑定($)。

最终目标是实现一个可以输入金额,点击按钮保存并累计总金额的“存钱罐”项目。

实现效果:

显示总金额

首先,我们需要在视图中显示“存钱罐”的总金额。

在 ContentView 中,声明一个变量来保存“存钱罐”的总金额。

@State private var amount = 0

接着,使用 Text 显示这个金额:

Text("\(amount)")
	.font(.largeTitle)
	.fontWeight(.bold)

这里,使用 .font 和 .fontWeight 设置字体的大小和粗细。

struct ContentView: View {
    
    @State private var amount = 0
    
    var body: some View {
        VStack {
	    Text("\(amount)")
	        .font(.largeTitle)
		.fontWeight(.bold)
	}
    }
}

当 amount 改变时,Text 显示的总金额也会自动刷新。

输入金额

“存钱罐”除了显示总金额,还需要让用户可以“输入”存取的金额,这就需要使用 SwiftUI 的视图控件 TextField。

TextField

TextField 是 SwiftUI 中用于输入内容的视图控件,通常用于单行输入。

TextField 主要提供了两种绑定格式:

1. 绑定字符串类型(String)

TextField("Placeholder", text: $text)

适合名字、标题等文本输入内容。

2. 绑定数值类型(Int/Double)

TextField("Amount", value: $number, format: .number)

适合年龄、薪资、金额等数字输入内容。

format: .number 表示这个输入框会按照“数字格式”进行解析和显示。

文本占位符

TextField 的第一个参数是占位符(Placeholder),用于提示用户输入内容:

TextField("input your name", text: $text)

当输入框为空时,会显示一段灰色的提示文字。

数据绑定

TextField 不负责持久化保存输入内容,需要通过绑定变量来管理数据。

@State private var text = ""
TextField("Placeholder", text: $text)

用户输入的内容会直接保存到 text 变量中,TextField 只负责输入界面。

$ 表示绑定(Binding):

$text

这不是普通变量,而是一个 Binding 类型。

它的作用是建立视图和数据之间的连接:

当用户在 TextField 中输入内容时,text 会自动更新;当 text 发生变化时,TextField 也会同步更新。

例如:

struct ContentView: View {
    @State private var text = ""
    
    var body: some View {
        VStack {
			Text("text:\(text)")
        	TextField("input your name", text: $text)
            	.frame(width: 150)
		}
    }
}

在 TextField 中输入内容,上方的 Text 会实时同步显示。

绑定数字类型

当需要输入数字时,需要绑定对应类型的变量:

@State private var number = 0

TextField("Amount", value: $number, format: .number)

当用户输入金额时,TextField 会将输入内容解析输入内容,并自动更新 number 的值。

添加输入框

在了解 TextField 的基本用法后,我们将它应用到“存钱罐”项目中。

“存钱罐”需要输入“金额”,所以我们使用“绑定数值类型(Int/Double)”的方式,并新增一个 number 变量来保存用户输入的金额:

struct ContentView: View {
    
    @State private var amount = 0
    @State private var number = 0
    
    var body: some View {
        VStack {
			Text("\(amount)")
            	.font(.largeTitle)
            	.fontWeight(.bold)
        	TextField("Amount", value: $number, format: .number)
		}
    }
}

现在,TextField 默认显示 number 的值(默认是 0)。

当清空输入内容时,会显示占位符“Amount”。

这也再次说明,TextField 显示的是绑定变量的值,而不是自己保存内容。

输入框尺寸问题

在当前视图中,我们会发现 TextField 没有边框,只显示一个 0,内容看上去是左对齐的。

效果如下:

这是因为,TextField 默认会占据父视图的全部宽度。

我们可以通过添加背景色来验证这一点:

TextField("Amount", value: $number, format: .number)
    .background(Color.red)

效果如下:

可以看到 TextField 实际上填充了整行宽度。

设置固定宽度

如果我们希望输入框更紧凑,可以使用 frame 限制其宽度:

TextField("Amount", value: $number, format: .number)
	.frame(width: 100)

效果如下:

添加边框和内边距

由于 TextField 默认没有边框,我们可以手动添加样式:

TextField("Amount", value: $number, format: .number)
    .frame(width: 100)
    .padding(5)
    .border(Color.black, width: 1)

现在,这个输入框看上去更像一个“标准输入框”。

边框

在 SwiftUI 中,border 用于为视图添加边框。

基本用法:

border(Color.black, width: 1)

其中,Color.black 表示边框的颜色,width 表示边框的粗细。

在 TextField 中,我们使用:

TextField("Amount", value: $number, format: .number)
    .frame(width: 100)
    .padding(5)
    .border(Color.black, width: 1)

这表示为输入框添加一个黑色,宽度为 1 pt 的边框。

也可以尝试更换其他颜色,比如 Color.blue、Color.green,或者加粗边框 width:2。

存钱按钮

现在,我们有一个用于显示总金额的 amount 变量,一个用于输入金额的 TextField,以及与输入框绑定的 number 变量。

当前代码如下:

struct ContentView: View {
    
    @State private var amount = 0
    @State private var number = 0
    
    var body: some View {
        VStack {
	    Text("\(amount)")
                .font(.largeTitle)
            	.fontWeight(.bold)
            TextField("Amount", value: $number, format: .number)
            	.frame(width: 100)
            	.padding(5)
            	.border(Color.black, width: 1)
	    }
    }
}

添加按钮

下面,我们需要添加一个按钮,来触发存钱操作。

Button("Save") {
    
}

实现存钱逻辑

我们想要实现用户输入金额,点击按钮,金额会自动累计到总金额。

Button("Save") {
    amount += number
}

这里使用“复合赋值运算符”,将用户输入的金额 number 叠加到 amount 总金额中。

重置输入金额

现在有一个问题,每次点击按钮,输入框中的金额不会清空。

当用户输入 10,点击保存,输入框中仍然保存 10,会影响到下次输入的存钱金额。

这是因为 TextField 绑定的是 number,我们点击按钮时,只修改了 amount,number 没有发生改变,所以输入框仍然显示旧值。

我们需要添加一个清除逻辑,当点击按钮后,先叠加存钱金额,再重置输入的金额:

Button("Save") {
    amount += number
    number = 0
}

现在,用户输入金额并点击按钮时,输入金额累加到总金额。number 重置为 0,以便用户的下一次输入。

我们就实现了“存钱罐”的所有存钱逻辑。

优化视图

在功能完成之后,我们可以对界面进行简单优化,添加背景图片和按钮样式。

添加按钮样式:

.buttonStyle(.borderedProminent)

添加背景图片:

.background {
    Image("1")
}

现在,我们完成了整个“存钱罐”的开发工作。

完整代码

struct ContentView: View {
    
    @State private var amount = 0
    @State private var number = 0
    
    var body: some View {
        VStack {
            Text("\(amount)")
                .font(.largeTitle)
                .fontWeight(.bold)
            TextField("Amount", value: $number, format: .number)
                .frame(width: 100)
                .padding(5)
                .border(Color.black, width: 1)
            Button("Save") {
                amount += number
                number = 0
            }
            .buttonStyle(.borderedProminent)
        }
        .background {
            Image("1")
        }
    }
}

实现效果:

现在,我们可以尝试存入 100 或者更多的钱,来检测“存钱罐”逻辑是否存在问题。

或者把“存钱罐”运行在模拟器或实体设备中,来体验我们开发的“存钱罐”应用。

调试输出

为了验证逻辑是否正确,我们还可以在按钮中加入调试逻辑,以验证输入的金额是否正确:

Button("Save") {
    print("---Saving---")
    amount += number
    number = 0
    print("amount:\(amount)")
    print("number:\(number)")
}

每次存钱并点击按钮时,我们可以看到对应的调试输出,以检查代码逻辑是否存在问题。

---Saving---
amount:11
number:0

   

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开发者。

欢迎加入我们的 微信交流群QQ交流群,交流更多精彩内容!
微信交流群二维码 QQ交流群二维码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注