那是完成的另一个项目,并且涵盖了大量的Swift和SwiftUI知识。还有更多项目需要涉及,但正如F1赛车手塞巴斯蒂安·维特尔(Sebastian Vettel)所说,“有时你需要按下暂停键,让所有内容沉入其中。”

今天是你暂停一下并让SwiftUI陷入困境的机会。完成审阅,应对挑战,如果需要,可以回到以前的合并日挑战并进行应对。

如此多的人通过电子邮件向我发送诸如“我能以多快的速度学习应用程序开发?”之类的问题。老实说,我为他们感到抱歉。赶时间你不会学。这两个目标与你的大脑不相容。专注学习是当我们通过学习积极地消费信息时,这确实很重要,而分散学习是当我们停止学习并让大脑被动地在已经学习的事物之间建立联系时。休息,睡觉或一段时间做其他事情都是该过程的重要部分。

因此,如果你急于赶上明天的新项目,请遵循维特尔的建议:按一下暂停,让所有内容沉入其中。

挑战

最好的学习方法之一是尽可能频繁地编写自己的代码,因此,你应该尝试以下三种方式扩展此应用程序,以确保你完全了解正在发生的事情。

  • 向其中添加“编辑/完成”按钮,ContentView以便用户可以更轻松地删除行。
  • 修改费用金额ContentView以包含一些样式,具体取决于它们的值-低于10美元的费用应使用一种样式,低于100美元的费用应使用另一种样式,而超过100美元的费用应采用第三种样式。这些样式取决于你。
  • 向中的“保存”按钮添加一些验证AddView。如果你输入“ fish”或其他无法转换为整数的内容,则显示警报,告诉用户问题出在哪里。

我的代码

ContentView.swift

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

import SwiftUI

struct ContentView: View {
@ObservedObject var expenses = Expenses()
@State private var showAddView = false

var body: some View {
NavigationView {
List {
ForEach(expenses.items) { item in
HStack {
VStack(alignment: .leading) {
Text(item.name)
.font(.title)
.bold()
Text(item.type)
.font(.footnote)
.foregroundColor(.gray)
}
Spacer()
Text("$\(item.amount)")
.font(.largeTitle)
.foregroundColor(self.colorChoose(num: item.amount))

.bold()
}
}
.onDelete(perform: removeItems)
}
.navigationBarTitle("iExpense")
.navigationBarItems(leading: EditButton(), trailing: Button(action: {
self.showAddView.toggle()
}) {
Image(systemName: "plus")
})
.sheet(isPresented: $showAddView){
AddView(expenses: self.expenses)
}
}
}

func removeItems(at offsets: IndexSet){
expenses.items.remove(atOffsets: offsets)
}

func colorChoose(num: Int) -> Color{
switch num {
case 0..<10:
return Color.black
case 10..<100:
return Color.green
default:
return Color.red
}
}
}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

struct ExpenseItem: Identifiable,Codable {
let id = UUID()
let name: String
let type: String
let amount: Int


}

class Expenses: ObservableObject {
@Published var items: [ExpenseItem]{
didSet {
let encoder = JSONEncoder()
if let encode = try? encoder.encode(items){
UserDefaults.standard.set(encode, forKey: "items")
}
}
}

init() {
if let items = UserDefaults.standard.data(forKey: "items"){
let decoder = JSONDecoder()

if let decoded = try? decoder.decode([ExpenseItem].self, from: items){
self.items = decoded
return
}
}
self.items = [ExpenseItem]()
}
}

1792

AddView.swift

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

import SwiftUI

struct AddView: View {
@State private var name = ""
@State private var type = "Personal"
@State private var amount = ""
@ObservedObject var expenses: Expenses
@Environment(\.presentationMode) var presentationMode
@State private var alertShow = false
@State private var alertText = "未知错误"

static let types = ["Bussiness", "Personal"]

var body: some View {
NavigationView {
Form {
Section(header: Text("Name")) {
TextField("Enter your name", text: $name)
}

Picker(selection: $type, label: Text("Type")) {
ForEach(AddView.self.types, id: \.self){
Text($0)
}
}

Section(header: Text("Amount")) {
TextField("Enter your amount", text: $amount)
.keyboardType(.numberPad)
}
}
.navigationBarTitle("Add new expense")
.navigationBarItems(leading: Button(action: {self.presentationMode.wrappedValue.dismiss()}) {
Text("Cansel")
} ,trailing: Button(action: {
if self.amount == "" {
self.alertShow = true
self.alertText = "价格中没有添加数字"
return
}
if let amount = Int(self.amount) {
let newinf = ExpenseItem(name: self.name, type: self.type, amount: amount)
self.expenses.items.append(newinf)

self.presentationMode.wrappedValue.dismiss()
}else{
self.alertShow = true
self.alertText = "添加出现错误,请检查价格是否是整数"
return
}


}) {
Text("Save")
}
)
.alert(isPresented: $alertShow){
Alert(---
title: Text("出现了错误"), message: Text(alertText), dismissButton: .default(Text("取消")))
}
}
}
}

struct AddView_Previews: PreviewProvider {
static var previews: some View {
AddView(expenses: Expenses())
}
}

1792

参考资料

查看下一天的SwiftUI学习笔记

关于100days英文课程