swift - SwiftUI - 与 Swift 相比,如何在应用程序中正确使用 func / struct?
问题描述
我对整个 SwiftUI 概念仍然是全新的,与其他(或称它们为旧的)编程风格相比,我发现它相当困难。我知道这可能听起来很傻,但我仍然没有掌握如何使用函数的概念。在大多数教程中,他们使用大量结构和计算属性,而函数显然不多(但为什么?)。虽然我可以设计漂亮的应用程序,而且 SwiftUI 与普通的 Swift / UIKit 相比是如此简单,但我不明白如何用有意义的代码填充我的应用程序,以便它们真正做一些事情。
好的,这是一些带有函数的示例代码。这是正确的方法还是我应该使用结构或其他东西?
此代码允许用户输入一个数字,当按下按钮时,数字会添加“5”,结果显示在 TextField 上方。没什么特别的,但我的问题是有人会使用这样的函数,还是有更好的方法来使用 SwiftUI?
struct ContentView: View {
@State private var result: String = "0"
@State private var number: String = ""
var body: some View {
VStack(alignment: .leading) {
Text("Result:")
.font(.title)
.fontWeight(.bold)
Text(String(result)).padding()
Text("Enter a number:")
.font(.title)
.fontWeight(.bold)
TextField("Enter a number", text: $number)
.textFieldStyle(RoundedBorderTextFieldStyle())
.keyboardType(.numberPad)
Button("Add 5") {
result = AddFive()
}
.frame(minWidth: 0, maxWidth: .infinity)
.padding()
.foregroundColor(.white)
.background(Color.red)
.cornerRadius(40)
.padding(.horizontal, 20)
}
.padding()
}
func AddFive() -> String {
let num = Int(number) ?? 0
let result = num + 5
return String(result)
}
}
当然,在这种情况下我可以使用计算属性,但我正在考虑更复杂的代码。在 Swift 中,我只是将一个函数叠加在另一个函数之上。
解决方案
你原来的方法大部分都很好。只是几点:
如果可能,尽量不要将数字存储为
String
变量。用于Int
数据操作。如果您需要从
String
输入中解析一个数字,您可以使用计算属性。简单的功能可以直接放在按钮里面。它们也可以作为方法提取。但是,更复杂的逻辑通常存储在 some
@ObservedObject
中,这就是为什么视图中没有很多函数的原因。逻辑被移到视图之外。
您可以尝试以下方法:
struct ContentView: View {
@State private var result = 0 // <- store as number
@State private var numberInput: String = ""
var number: Int { // <- computed property for calculations using `numberInput`
Int(numberInput) ?? 0
}
var body: some View {
VStack(alignment: .leading) {
Text("Result:")
.font(.title)
.fontWeight(.bold)
Text("\(result)") // <- display `Int` in `Text` views
.padding()
Text("Enter a number:")
.font(.title)
.fontWeight(.bold)
TextField("Enter a number", text: $numberInput)
.textFieldStyle(RoundedBorderTextFieldStyle())
.keyboardType(.numberPad)
Button("Add 5") {
self.result = self.number + 5
}
.frame(minWidth: 0, maxWidth: .infinity)
.padding()
.foregroundColor(.white)
.background(Color.red)
.cornerRadius(40)
.padding(.horizontal, 20)
}
.padding()
}
}
这是使用 的另一种方法@ObservedObject
:
class ViewModel: ObservableObject {
@Published var result = 0
@Published var numberInput: String = ""
var number: Int {
Int(numberInput) ?? 0
}
func incrementNumber(by number: Int) {
self.result = self.number + number
}
}
struct ContentView: View {
@ObservedObject private var viewModel = ViewModel()
var body: some View {
VStack(alignment: .leading) {
Text("Result:")
.font(.title)
.fontWeight(.bold)
Text("\(viewModel.result)").padding()
Text("Enter a number:")
.font(.title)
.fontWeight(.bold)
TextField("Enter a number", text: $viewModel.numberInput)
.textFieldStyle(RoundedBorderTextFieldStyle())
.keyboardType(.numberPad)
Button("Add 5") {
self.viewModel.incrementNumber(by: 5)
}
.frame(minWidth: 0, maxWidth: .infinity)
.padding()
.foregroundColor(.white)
.background(Color.red)
.cornerRadius(40)
.padding(.horizontal, 20)
}
.padding()
}
}
推荐阅读
- python - 我似乎无法让我的 openpyxl 代码工作
- xml - 当结构正确时,结构的 SOAP 错误消息
- java - Jersey 2 和 Jetty:检测到未知的 HK2 故障
- html - 为什么 Reactjs 会移除 inline-block 元素之间的水平空间?
- c# - 在 switch 中设置的委托不能在 switch 之外使用
- java - 带有可选结尾逗号的正则表达式模式匹配
- mysql - 使用全文索引和其他带索引的列优化 mysql 查询
- sql - 如何在 SQL 中有效地对一组列进行转置和求和?
- c# - 如何从 OnTextChanged 事件中获取 GridViewEventArgs?
- google-maps - 在颤振中实现短信“分享我的当前位置”