苹果电脑可以自学编程吗,苹果电脑自学编程

首页 > 经验 > 作者:YD1662022-11-09 04:01:56

表面上和前一小节没有变化,但是内部的数据结构变为了自定义结构体,后续就可以愉快地持续扩展结构体里的属性了。

输入框和按钮

对待办清单 App 来说,光有列表还不够,最起码得能输入新条目。所以得添加以下两个控件:

新增以下代码:

struct ContentView: View { @State private var todoList = [ // 省略已有代码 ... ] // 新增本地状态 newName // 用于接收用户输入的文本 @State private var newName: String = "" var body: some View { // 新增代码 // VStack: 垂直方向布局 VStack { // HStack: 水平方向布局 HStack { // 文本控件 TextField("输入新事项", text: $newName) // 按钮控件 Button("确认") { // 点击按钮后执行的操作 let newItem = ToDoItem(name: newName) todoList.append(newItem) newName = "" } } .padding() // 省略已有代码 List { // ... } } } }

有点轻车熟路了对吧,在 Swift 的世界里,尽量不让你指挥它“这个控件要如何执行初始化、那个界面要如何添加对象”,你只要告诉它“这里有什么”就行。

稍微研究下新写的代码:

重新渲染模拟器,看看效果:

苹果电脑可以自学编程吗,苹果电脑自学编程(9)

由于输入效果是动态的,所以你需要点一下上图箭头指的那个按钮,让渲染从静态切换为动态。

然后随便输入点东西,并点击确认按钮:

苹果电脑可以自学编程吗,苹果电脑自学编程(10)

顺利的话,新条目就添加到列表里了:

苹果电脑可以自学编程吗,苹果电脑自学编程(11)

怎么样,是不是有点意思?

让我们更进一步

经过上面的折腾,虽然我们已经把列表数据转化为自定义结构体 ToDoItem() 了,但数据和界面还可以进一步解耦。随着项目逐渐扩展,程序架构需要更明确的分层和细化。

如果把 UI 界面描述为视图(View),数据描述为模型(Model),那么我们还需要一个桥梁,帮助视图和模型进行多对多的通信和数据流的双向绑定。

这个桥梁在上面的代码中是没有的,因此先来写它。

实际写项目时应该把视图、模型和“桥梁”都作为单独的文件。本文为了方便就没这么做了。

新增一个 ToDoViewModel 类如下:

class ToDoViewModel: ObservableObject { // @Published 装饰需要进行绑定的数据 @Published private(set) var todoList: [ToDoItem] // 初始化 init() { self.todoList = [ ToDoItem(name: "Apple"), ToDoItem(name: "Pear"), ToDoItem(name: "Tomato") ] } // 新增数据条目 func append(_ item: ToDoItem) { todoList.append(item) } // 改变条目是否完成的状态 func toggle(_ item: ToDoItem) { // 这一行代码将 item 的 id 赋值给 index 变量 // 语法原理暂时不要去深究 if let index = todoList.firstIndex(where: {$0.id == item.id}) { // toggle() 函数将布尔值反转 todoList[index].isOn.toggle() } } }

这个类的关键就在于用 @Published 装饰的 todoList ,它就是需要和视图进行绑定的数据模型。视图不应该直接修改模型,所以你看到有关键字 private(set) 限制了类外部的指令只能读取不能修改。对模型的修改要通过 ToDoViewModel 内置的方法。“桥梁类”里可以有多个 @Published 装饰的模型,也可以提供给多个视图使用。

接下来的模型没有变化,还是之前的那个结构体:

struct ToDoItem: Identifiable { let id = UUID() var isOn = true let name: String }

最后是视图,稍微有点长:

struct ContentView: View { // @StateObject 用于自定义的“桥梁类”,作用和前面的 @State 差不多 @StateObject private var viewModel = ToDoViewModel() // newName 状态无改动 @State private var newName: String = "" var body: some View { VStack { // 之前的 TextField 和 Button // 无改动 HStack { // ... } .padding() List { ForEach(viewModel.todoList) { item in HStack { // .foregroundColor 根据 isOn 的状态改变文本的颜色 // (a ? b : c) 被称为三元操作符 Text(item.name) .foregroundColor(item.isOn ? .primary : .gray) // 在两个元素间填充占位的空白 Spacer() // Group 里模拟了单选框 // Group 是和 VStack 类似的布局对象 // 注意它里面是可以写 if 这种控制流语句的 // 根据 isOn 的值,改变单选框的外观 Group { if item.isOn { // Image 调用了内置的图片 // "circle" 是个中空的圈 Image(systemName: "circle") } else { // 中间带勾的圈 Image(systemName: "checkmark.circle.fill") } } // 将单选框渲染为蓝色 .foregroundColor(.blue) // 定义了单选框的点击事件 // 点击后触发了“桥梁”类的 toggle() 方法 .onTapGesture { viewModel.toggle(item) } } } } } } }

看起来改了很多,但其实真的挺简单的:

来看看效果。刷新模拟器:

苹果电脑可以自学编程吗,苹果电脑自学编程(12)

上一页1234下一页

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.