【问题标题】:SwiftUI - how to properly use func / struct in an app compared to Swift?SwiftUI - 与 Swift 相比,如何在应用程序中正确使用 func / struct?
【发布时间】:2020-07-05 10:44:56
【问题描述】:

我对整个 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 中,我只是将一个函数叠加在另一个函数之上。

【问题讨论】:

  • 我认为大多数时候你会从一个事件中触发一个动作,比如按钮动作,onAppear。您可以直接在 Button 操作中执行命令,也可以像上面那样将代码外包给一个函数。大多数都是关于修改类/结构数据或更改状态/绑定。许多不同的方法,但请确保您上面的方法可以正常工作。
  • 当您的应用程序增长时,您开始使用 func/struct。加入一些网络以进行更深入的讨论。

标签: swift function struct swiftui


【解决方案1】:

您最初的方法大部分都很好。只是几点:

  • 如果可能,尽量不要将数字存储为String 变量。使用Int 进行数据操作。

  • 如果您需要解析来自String 输入的数字,您可以使用计算属性。

  • 简单的功能可以直接放在按钮里面。它们也可以作为方法提取。然而,更复杂的逻辑通常存储在一些@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()
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-14
    相关资源
    最近更新 更多