首页 > 解决方案 > 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 中,我只是将一个函数叠加在另一个函数之上。

标签: swiftfunctionstructswiftui

解决方案


你原来的方法大部分都很好。只是几点:

  • 如果可能,尽量不要将数字存储为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()
    }
}

推荐阅读