I am still totally new to the whole SwiftUI concept and I find it quite difficult compared to other (or lets call them older) programing styles. I know this might sound silly, but I still don't grasp the concept of how to use functions. In most tutorials they use lots of structs and computed properties and apparently not many functions (but why?). I can design nice looking apps though and SwiftUI is so simply compared to normal Swift / UIKit, but I don't understand how to fill my apps with meaningful code so that they actually do something.
Okay here is some example code with a function. Is this the right way to do this or should I use structs or something else?
This code lets the user enter a number, and when the button is pressed "5" is added to the number and the result is shown above the TextField. Nothing special, but my question is would one use a function like this or is there a better way to do this with 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)
}
}
Of course I could use a computed property in this case, but I am thinking about much more complex code. In Swift I just pilled one function on top of the other.
Your original approach is mostly fine. Just a few points:
if possible try not to store numbers as String
variables. Use Int
for data manipulation.
if you need to parse a number from a String
input you can use computed properties.
simple functions can be placed directly inside buttons. They can be also extracted as methods. However, more complex logic is usually stored inside some @ObservedObject
and that's why there aren't many functions in views. The logic is moved outside the view.
You may try the following:
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()
}
}
Here is an alternative approach using an @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()
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.