SwiftUI & ChatGPT. The world is changing. Again.
Fast app prototyping with SwiftUI & ChatGPT
Everything that follows from this point forward is my input prompts, followed by ChatCGP’s responses, complete with sample code.
Hey ChatGPT, can you make a SwiftUI registration form with name, address and city fields?
import SwiftUI
struct RegistrationForm: View {
@State private var name: String = ""
@State private var address: String = ""
@State private var city: String = ""
var body: some View {
Form {
TextField("Name", text: $name)
TextField("Address", text: $address)
TextField("City", text: $city)
}
}
}
The?RegistrationForm?struct conforms to the?View?protocol and defines a?body?property that returns a?Form?view. The?Form?view contains?TextField views for each of the form fields, and the?@State?property wrapper is used to manage the state of each field.
Can you move the fields to a view model?
Move the form fields to a separate view model in order to better manage the state and logic of the form.
import SwiftUI
struct RegistrationForm: View {
@ObservedObject var viewModel: RegistrationFormViewModel
var body: some View {
Form {
TextField("Name", text: $viewModel.name)
TextField("Address", text: $viewModel.address)
TextField("City", text: $viewModel.city)
}
}
}
class RegistrationFormViewModel: ObservableObject {
@Published var name: String = ""
@Published var address: String = ""
@Published var city: String = ""
}
The?RegistrationForm?struct has an?@ObservedObject?property that references an instance of the?RegistrationFormViewModel?class. This allows the?RegistrationForm?view to bind to the properties of the view model using the?$?prefix, just as it did with the?@State?properties in the previous example.
The?RegistrationFormViewModel?class defines?@Published?properties for each of the form fields, which allows the view to be notified when the values of these properties change. This allows the view to update automatically when the user changes the form fields.
This approach helps to keep the view logic and state management separate from the view itself, making the code easier to understand and maintain.
What if I need to validate that none of the fields are empty?
If you need to validate that none of the fields in the form are empty, you can add a method to the?RegistrationFormViewModel?class that checks the values of the form fields and returns a?Bool?indicating whether the form is valid or not.
class RegistrationFormViewModel: ObservableObject {
@Published var name: String = ""
@Published var address: String = ""
@Published var city: String = ""
var isValid: Bool {
return !name.isEmpty && !address.isEmpty && !city.isEmpty
}
}
The?isValid?property uses the?isEmpty?property of each of the form fields to determine whether the form is valid or not. If all of the fields are not empty, the?isValid?property will return?true, otherwise it will return?false.
You can then use this property in the view to enable or disable a submit button or to display an error message if the form is not valid.
struct RegistrationForm: View {
@ObservedObject var viewModel: RegistrationFormViewModel
var body: some View {
Form {
TextField("Name", text: $viewModel.name)
TextField("Address", text: $viewModel.address)
TextField("City", text: $viewModel.city)
if !viewModel.isValid {
Text("All fields are required")
.foregroundColor(.red)
}
}
}
}
The?RegistrationForm?view checks the value of the?isValid?property and, if the form is not valid, it displays an error message using a?Text?view. This allows the user to know which fields need to be filled out in order to make the form valid.
Can we add a Save button to that form?
Add a Save button to the form by using a?Button?view in the?RegistrationForm?struct.
struct RegistrationForm: View {
@ObservedObject var viewModel: RegistrationFormViewModel
var body: some View {
Form {
TextField("Name", text: $viewModel.name)
TextField("Address", text: $viewModel.address)
TextField("City", text: $viewModel.city)
if !viewModel.isValid {
Text("All fields are required")
.foregroundColor(.red)
}
Button(action: {
// Save the form data here
}) {
Text("Save")
}
.disabled(!viewModel.isValid)
}
}
}
The?RegistrationForm?view includes a?Button?view with an action closure that is called when the button is tapped. This closure can be used to save the form data to a database or other storage location.
The?Button?view also has a?disabled?modifier that disables the button if the?isValid?property of the?RegistrationFormViewModel?is?false. This ensures that the form must be filled out correctly before the user can save the data.
Can you create a User struct based on the form information?
A?User?struct that could be used to represent the data from the form:
领英推荐
struct User {
var name: String
var address: String
var city: String
}
This User struct defines properties for each of the form fields, such as?name,?address?and?city. These properties can be used to store the values entered by the user in the form.
Create an instance of the?User?struct using the values from the form:
let user = User(
name: viewModel.name,
address: viewModel.address,
city: viewModel.city
)
The?user?constant is initialized with the values from the?RegistrationFormViewModel?instance. You can then use this?User?instance to save the data to a database or other storage location, or to pass the data to another part of your app for further processing.
And how do I populate the fields on the view model from the struct?
class RegistrationFormViewModel: ObservableObject {
@Published var name: String = ""
@Published var address: String = ""
@Published var city: String = ""
var isValid: Bool {
return !name.isEmpty && !address.isEmpty && !city.isEmpty
}
func populate(with user: User) {
name = user.name
address = user.address
city = user.city
}
}
Use this method to populate the form fields:
let user = User(
name: "Oliver Doe",
address: "100 Main St",
city: "Anytown"
)
viewModel.populate(with: user)
The?user?constant is initialized with some sample data, and then the?populate(with:)?method is called on the?viewModel?instance, passing in the?user?instance as a parameter. This will set the values of the view model's properties to match the values of the?User?instance, which will in turn populate the form fields with the data from the?User?instance.
Full Version / DEV Community
Contacts
I have a clear focus on time-to-market and don't prioritize technical debt. And I took part in the Pre-Sale/RFX activity as a System Architect, assessment efforts for Mobile (iOS-Swift, Android-Kotlin), Frontend (React-TypeScript) and Backend (NodeJS-.NET-PHP-Kafka-SQL-NoSQL). And I also formed the work of Pre-Sale as a CTO from Opportunity to Proposal via knowledge transfer to Successful Delivery.
?? Email:?[email protected]
?? LinkedIn:?https://www.dhirubhai.net/in/sergeyleschev/
?? LeetCode:?https://leetcode.com/sergeyleschev/
?? Twitter:?https://twitter.com/sergeyleschev
?? Github:?https://github.com/sergeyleschev
?? Website:?https://sergeyleschev.github.io
?? DEV Community: https://dev.to/sergeyleschev
?? Reddit: https://reddit.com/user/sergeyleschev
?? Quora: https://quora.com/sergey-leschev
?? Medium: https://medium.com/@sergeyleschev