Tap gesture on buttons response randomly in SwiftUI - swiftui

I have a My Profile form in my app. In the form I have some buttons. Among them 5 buttons are used to present custom drop down menus to select Sax, Blood, Nationality, and so on. However, when I tap these buttons sometime they response some time don't. For example, if I tap them 10 time they response 2 or 3 times. Some time they work for long tap. I have spent days on this matter, but could not identify any problem in my code. Is there anyone who faced this sort of problems? Could anyone figure out what is the actual problem. By the way, all other buttons in my app working absolutely fine.
This is the code for first 3 buttons in red rectangle in the picture
import SwiftUI
struct FormPartTwoView: View {
#Binding var gender: String
#Binding var blood: String
#Binding var nationality: String
#Binding var showingGenderPicker: Bool
#Binding var showingBloodGroupPicker: Bool
#Binding var showingNationalityPicker: Bool
#ObservedObject var userProfile = UserProfileViewModel()
#ObservedObject var userProfileUpdate = UserProfileUpdateViewModel()
var body: some View {
GeometryReader { geometry in
HStack {
Button(action: {
self.showingGenderPicker.toggle()
self.showingBloodGroupPicker = false
self.showingNationalityPicker = false
}) {
VStack {
TextField("Gender", text: self.$gender)
.padding(.horizontal)
.disabled(true)
}
.font(.system(size: 13))
.frame(height: 40)
.overlay(
RoundedRectangle(cornerRadius: 5)
.stroke(Color("Border2"), lineWidth: 1)
)
}
.buttonStyle(PlainButtonStyle())
Button(action: {
self.showingBloodGroupPicker.toggle()
self.showingGenderPicker = false
self.showingNationalityPicker = false
}) {
VStack {
TextField("Blood", text: self.$blood)
.padding(.horizontal)
.disabled(true)
}
.font(.system(size: 13))
.frame(height: 40)
.overlay(
RoundedRectangle(cornerRadius: 5)
.stroke(Color("Border2"), lineWidth: 1)
)
}
.buttonStyle(PlainButtonStyle())
Button(action: {
self.showingNationalityPicker.toggle()
self.showingGenderPicker = false
self.showingBloodGroupPicker = false
}) {
VStack {
TextField("Nationality", text: self.$nationality)
.padding(.horizontal)
.disabled(true)
}
.font(.system(size: 13))
.frame(height: 40)
.overlay(
RoundedRectangle(cornerRadius: 5)
.stroke(Color("Border2"), lineWidth: 1)
)
}
.buttonStyle(PlainButtonStyle())
}
.frame(width: geometry.size.width, height: 40)
}
}
}
struct FormPartTwoView_Previews: PreviewProvider {
static var previews: some View {
FormPartTwoView(gender: .constant(""), blood: .constant(""), nationality: .constant(""), showingGenderPicker: .constant(false), showingBloodGroupPicker: .constant(false), showingNationalityPicker: .constant(false))
}
}
This is the code for second tow Buttons:
import SwiftUI
struct FormPartFiveView: View {
#Binding var district: String
#Binding var upazila: String
#Binding var postcode: String
#Binding var showingUpazilaPicker: Bool
#Binding var showingDistrictPicker: Bool
#ObservedObject var userProfileUpdate = UserProfileUpdateViewModel()
var body: some View {
GeometryReader { geometry in
HStack {
Button(action: {
self.showingDistrictPicker.toggle()
self.showingUpazilaPicker = false
}) {
VStack {
Text("\(self.district == "" ? "District" : self.district)")
.foregroundColor(self.district == "" ? Color.gray : Color.black)
.padding(.horizontal)
}
.font(.system(size: 13))
.frame(width: geometry.size.width/3.2, height: 40)
.overlay(
RoundedRectangle(cornerRadius: 5)
.stroke(Color("Border2"), lineWidth: 1)
)
}
.buttonStyle(PlainButtonStyle())
Button(action: {
self.showingUpazilaPicker.toggle()
self.showingDistrictPicker = false
}) {
VStack {
Text("\(self.upazila == "" ? "Upazila" : self.upazila)")
.foregroundColor(self.upazila == "" ? Color.gray : Color.black)
.padding(.horizontal)
}
.font(.system(size: 13))
.frame(width: geometry.size.width/3.2, height: 40)
.overlay(
RoundedRectangle(cornerRadius: 5)
.stroke(Color("Border2"), lineWidth: 1)
)
}
.buttonStyle(PlainButtonStyle())
VStack {
TextField("Postcode", text: self.$postcode)
.padding(.horizontal)
}
.font(.system(size: 13))
.frame(width: 100, height: 40)
.overlay(
RoundedRectangle(cornerRadius: 5)
.stroke(Color("Border2"), lineWidth: 1)
)
}
.frame(width: geometry.size.width, height: 40)
}
}
}
struct FormPartFiveView_Previews: PreviewProvider {
static var previews: some View {
FormPartFiveView(district: .constant(""), upazila: .constant(""), postcode: .constant(""), showingUpazilaPicker: .constant(false), showingDistrictPicker: .constant(false))
}
}

Related

image picker in swift showing abnormal behaviour while selecting an image from gallery

when i pick an image using Image Picker from my Quick add View it kills all previous views and take me to the HomePage Tab which is Meal Planner View.Sometimes it works normal only on IOS device. It never works fine on simulator as i tried different simulators in Xcode. It also works fine in simulator and IOS device when i remove my TabBar and run directly from Meal Planner View.
kindly suggest something helpful.
import SwiftUI
struct QuickAddView: View {
#Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
var viewName: String
#ObservedObject var vm = MealViewModel()
#State private var showPicker = false
#State private var selectedImage: UIImage?
#State var mealTitle: String = ""
#State var text: String = ""
// #State var descrption: String = ""
var body: some View {
VStack{
navBarView()
ScrollView(showsIndicators: false){
VStack {
VStack(alignment: .leading) {
Button {
self.showPicker.toggle()
} label: {
if selectedImage == nil {
ZStack {
Image("qorma")
.resizable()
.frame( height: 100)
HStack{
Text("+").font(.custom(Nunito.Bold.rawValue, size: 22))
.foregroundColor(.white)
Text("Attach a Photo").font(.custom(Nunito.Regular.rawValue, size: 20))
.foregroundColor(.white)
}
}
}
else {
ZStack {
Image(uiImage: selectedImage!)
.resizable()
.frame( height: 100)
HStack{
Text("+").font(.custom(Nunito.Bold.rawValue, size: 22))
.foregroundColor(.white)
Text("Attach a Photo").font(.custom(Nunito.Regular.rawValue, size: 20))
.foregroundColor(.white)
}
}
}
}
}
CustomTextField(text: $vm.title, placeHolder: "Name")
.background(.white)
.padding([.vertical],30)
fields()
TextEditor(text: $vm.description)
.textFieldStyle(.roundedBorder)
.colorMultiply(.white)
.frame( height: 199)
.border(.gray, width: 0.5)
.cornerRadius(10)
.shadow(radius: 1)
.foregroundColor(.gray)
.padding([.top],30)
addButton()
}
}
}.padding()
.sheet(isPresented: $showPicker) {
ImagePicker(image: $selectedImage)
}
}
}
extension QuickAddView {
func nutrientFields(nutrientTitle: String,amount: Binding<String>) -> some View {
VStack(alignment: .leading){
HStack(){
Text(nutrientTitle)
.font(.custom(Nunito.Semibold.rawValue, size: 24))
.foregroundColor(.gray)
Spacer()
HStack{
ZStack{
TextField("0", text: amount)
.font(Font.system(size: 30))
.background(Color.white)
.foregroundColor(Color(ColorName.appAqua.rawValue))
.frame(width: 70)
}
.background(
Rectangle()
.foregroundColor(Color.white)
.opacity(0.2)
)
.overlay(
RoundedRectangle(cornerRadius: 5)
.stroke(Color(ColorName.appAqua.rawValue), lineWidth: 2.5)
)
Text("(g)")
.font(.custom(Nunito.Semibold.rawValue, size: 30))
.foregroundColor(Color(ColorName.appAqua.rawValue))
}.padding([.horizontal])
// .font(.custom(Nunito.Semibold.rawValue, size: 20))
// .foregroundColor(Color(ColorName.appAqua.rawValue))
// .frame(width: 40, height: 30)
}
}
}
func calorieField (nutrientTitle: String,amount: Binding<String>) -> some View {
VStack(alignment: .leading){
HStack(){
Text(nutrientTitle)
.font(.custom(Nunito.Semibold.rawValue, size: 24))
.foregroundColor(.gray)
Spacer()
HStack{
ZStack{
TextField("0", text: amount)
.font(Font.system(size: 30))
.background(Color.white)
.foregroundColor(Color(ColorName.appAqua.rawValue))
.frame(width: 70)
}
.background(
Rectangle()
.foregroundColor(Color.white)
.opacity(0.2)
)
.overlay(
RoundedRectangle(cornerRadius: 5)
.stroke(Color(ColorName.appAqua.rawValue), lineWidth: 2.5)
)
}.padding([.horizontal],59)
}
}
}
func fields() -> some View {
VStack(spacing: 20){
calorieField(nutrientTitle: "Calories",amount: $vm.cals)
Rectangle()
.fill(.gray)
.frame( height: 1)
nutrientFields(nutrientTitle: "Carbohydrates",amount: $vm.carb)
Rectangle()
.fill(.gray)
.frame( height: 1)
nutrientFields(nutrientTitle: "Proteins",amount: $vm.aminos)
Rectangle()
.fill(.gray)
.frame( height: 1)
nutrientFields(nutrientTitle: "Fats",amount: $vm.lipids)
}
}
func navBarView() -> some View {
ZStack {
HStack{
Button ( action: { self.presentationMode.wrappedValue.dismiss() },
label: {
Image(systemName: "arrow.backward").frame(width: 16, height: 16)
.foregroundColor(Color(ColorName.appAqua.rawValue))
})
Spacer()
}
Text("Quick Add")
.font(.custom(Nunito.Bold.rawValue, size: 22.5))
.foregroundColor(Color(ColorName.appAqua.rawValue))
}
}
func addButton() -> some View {
// NavigationLink(
// destination: BreakFastMainView(viewName: viewName, firebaseId: UserDefaults.standard.value(forKey: "FireBaseId") as! String) .navigationBarTitle("")
// .navigationBarHidden(true)
// ,
Button {
vm.addMealData(category: viewName, image: selectedImage ?? UIImage(), name: vm.title, cals: vm.cals, carbs: vm.carb, protein: vm.aminos, fat: vm.lipids, description: vm.description, firebaseId: UserDefaults.standard.value(forKey: "FireBaseId") as? String ?? "12345", action: {
self.presentationMode.wrappedValue.dismiss()
})
}
label: {
ZStack {
RoundedRectangle(cornerRadius: 10)
.frame(height: 50)
.foregroundColor(Color("btnBlue"))
Text("Add")
.font(.custom("Nunito-Bold", size: 20))
.foregroundColor(.white)
}.padding([.top], 32)
}
}
func data(_ name: String, _ amount: String) -> some View {
ZStack(alignment: .leading) {
RoundedRectangle(cornerRadius: 5)
.stroke( .gray, lineWidth: 0.5)
.frame(height: 56)
HStack {
Text(name)
.foregroundColor( .gray)
.font(.custom(Nunito.Semibold.rawValue, size: 20))
Spacer()
Text(amount)
.foregroundColor( Color(ColorName.appAqua.rawValue))
.font(.custom(Nunito.Semibold.rawValue, size: 20))
Text("g")
.foregroundColor( Color(ColorName.appAqua.rawValue))
.font(.custom(Nunito.Semibold.rawValue, size: 20))
}.padding()
}
}
}
struct QuickAddView_Previews: PreviewProvider {
static var previews: some View {
QuickAddView( viewName: "dfd")
}
}

Dropwn list menu open behind of other Views in SwiftUi

When I make dropdown list menu in SwiftUi, dropdown list shows behind of other Component View, I've tried to zIndex(1) at the last of the VStack, and I've tried .overlay at the top of the Stack but it didn't solve my problem, I've shared below code and I've shared screenshot of the problem, how can I solve this problem? thanks...
import SwiftUI
struct DropdownOption: Hashable {
let key: String
let value: String
public static func == (lhs: DropdownOption, rhs: DropdownOption) -> Bool {
return lhs.key == rhs.key
}
}
struct DropdownRow: View {
var option: DropdownOption
var onOptionSelected: ((_ option: DropdownOption) -> Void)?
var body: some View {
Button(action: {
if let onOptionSelected = self.onOptionSelected {
onOptionSelected(self.option)
}
}) {
HStack {
Text(self.option.value)
.font(.system(size: 14))
.foregroundColor(Color.black)
Spacer()
}
}
.padding(.horizontal, 16)
.padding(.vertical, 5)
}
}
struct Dropdown: View {
var options: [DropdownOption]
var onOptionSelected: ((_ option: DropdownOption) -> Void)?
var body: some View {
ScrollView {
VStack(alignment: .leading, spacing: 0) {
ForEach(self.options, id: \.self) { option in
DropdownRow(option: option, onOptionSelected: self.onOptionSelected)
}
}
}
.frame(minHeight: CGFloat(options.count) * 30, maxHeight: 250)
.padding(.vertical, 5)
.background(Color.white)
.cornerRadius(5)
.overlay(
RoundedRectangle(cornerRadius: 5)
.stroke(Color.gray, lineWidth: 1)
)
}
}
struct DropdownSelector: View {
#State private var shouldShowDropdown = false
#State private var selectedOption: DropdownOption? = nil
var placeholder: String
var options: [DropdownOption]
var onOptionSelected: ((_ option: DropdownOption) -> Void)?
private let buttonHeight: CGFloat = 45
var body: some View {
Button(action: {
self.shouldShowDropdown.toggle()
}) {
HStack {
Text(selectedOption == nil ? placeholder : selectedOption!.value)
.font(.system(size: 14))
.foregroundColor(selectedOption == nil ? Color.gray: Color.black)
Spacer()
Image(systemName: self.shouldShowDropdown ? "arrowtriangle.up.fill" : "arrowtriangle.down.fill")
.resizable()
.frame(width: 9, height: 5)
.font(Font.system(size: 9, weight: .medium))
.foregroundColor(Color.black)
}
}
.padding(.horizontal)
.cornerRadius(5)
.frame(width: .infinity, height: self.buttonHeight)
.overlay(
RoundedRectangle(cornerRadius: 5)
.stroke(Color.gray, lineWidth: 1)
)
.overlay(
VStack {
if self.shouldShowDropdown {
Spacer(minLength: buttonHeight + 10)
Dropdown(options: self.options, onOptionSelected: { option in
shouldShowDropdown = false
selectedOption = option
self.onOptionSelected?(option)
})
}
}, alignment: .topLeading
)
.background(
RoundedRectangle(cornerRadius: 5).fill(Color.white)
)
}
}
calling DropDownList
ZStack(alignment:.top){
HStack {
Group {
DropdownSelector(
placeholder: "Choose Aircraft Type",
options: options,
onOptionSelected: { option in
print(option)
})
.padding(.horizontal)
}
}.padding(.top, 50)
HStack {
Group {
DropdownSelector(
placeholder: "Choose Simulator Type",
options: optionsSimulator,
onOptionSelected: { option in
print(option)
})
.padding(.horizontal)
}
}.padding(.top, 50)
}

Can't sheet with button in ListView SwiftUI

I have a list. In the List there are 2 buttons.
I want to click on each button to present another view with Sheet.
When I first click it it works, but the second time or another tap button it doesn't present the view. Hope you can help me.
My code
My design
Read up on how to use Buttons and sheets. Typically Buttons triggering a sheet is used like this:
EDIT: with suggestion from Philip Dukhov, replace:
Button("Learning") {
}.sheet(isPresented: $isLearning, content: {
LearningView()
})
.onTapGesture {
self.isLearning = true
}
with:
Button(action: {isLearning = true}) {
Text("Learning")
}
.sheet(isPresented: $isLearning) {
LearningView()
}
and do the same for "Test" button, with "isTest" instead of "isLearning" and "TestViewCategory()" instead of "LearningView()".
EDIT 2:
Update "TestView" with:
struct TestView: View {
var title = ""
let models = modelItems
var body: some View {
ScrollView {
VStack {
ForEach(models) { model in
TopicList(model: model)
}
}
}
.navigationBarTitle(title, displayMode: .inline)
.onAppear {
UITableView.appearance().separatorStyle = .none
}
.animation(.spring())
}
}
EDIT 3: here is the test code that works for me:
import SwiftUI
#main
struct TestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
var body: some View {
NavigationView {
TestView()
}
}
}
struct ButtonView: View {
#State var isLearning: Bool = false
#State var isTest: Bool = false
var body: some View {
HStack {
Button(action: {isLearning = true}) {
Text("Learning")
}
.sheet(isPresented: $isLearning) {
Text("LearningView")
}
.font(.system(size: 16))
.frame(width: 132 , height: 48)
.background(Color(.white))
.overlay(
RoundedRectangle(cornerRadius: 30)
.stroke(Color(#colorLiteral(red: 0.9259920716, green: 0.9261471629, blue: 0.9259716272, alpha: 1)), lineWidth: 1)
)
Button(action: {isTest = true}) {
Text("Test")
}
.sheet(isPresented: $isTest) {
Text("TestViewCategory")
}
.font(.system(size: 16))
.frame(width: 132 , height: 48)
.background(Color(.white))
.overlay(
RoundedRectangle(cornerRadius: 30)
.stroke(Color(#colorLiteral(red: 0.9259920716, green: 0.9261471629, blue: 0.9259716272, alpha: 1)), lineWidth: 1)
)
}
}
}
struct TopicList: View {
// for testing
let model: String
#State private var showSubItem = false
var body: some View {
VStack {
HStack {
Image(systemName: showSubItem ? "arrow.up.circle" : "arrow.down.circle")
.resizable()
.frame(width: 26, height: 26)
.onTapGesture {
withAnimation {
showSubItem.toggle()
}
}
VStack {
VStack(alignment: .leading) {
Text("title")
.font(.custom("Poppins-Regular", size: 24))
.padding(.top,9)
.padding(.bottom,4)
HStack {
Text("Open date")
.font(.custom("Poppins-Regular", size: 12))
Text("Open date")
.font(.custom("Poppins-Regular", size: 12))
Text("Due date")
.font(.custom("Poppins-Regular", size: 12))
Text("Due date")
.font(.custom("Poppins-Regular", size: 12))
}
}
.padding(.leading,17)
.frame(width: 320, height: 70)
.fixedSize(horizontal: false, vertical: true)
if showSubItem {
ButtonView()
.padding(.top,12)
.fixedSize(horizontal: false, vertical: true)
.transition(.opacity)
.transition(.slide)
.padding(.bottom,13)
}
}
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(Color(#colorLiteral(red: 0.9259920716, green: 0.9261471629, blue: 0.9259716272, alpha: 1)), lineWidth: 1)
)
}
}
}
}
struct TestView: View {
var title = "nav title"
let models = ["1","2","3"]
var body: some View {
ScrollView {
VStack {
ForEach(models, id: \.self) { model in
TopicList(model: model)
}
}
}
.navigationBarTitle(title, displayMode: .inline)
.onAppear {
UITableView.appearance().separatorStyle = .none
}
.animation(.spring())
}
}

SwiftUI: Tapping the return key of keyboard erases all the form data

I have forms in my SwiftUI app. In some of them there is a problem relating to keyboard's return key. After editing the form, when I tap the return key to resign the keyboard it erases all the edited data in the form. I could not find any reasonable cause of this problem. I have many network calls in the app.
Here is the code of the login form:
import SwiftUI
struct FormView: View {
var size: CGSize
#State private var errorMessage: String = ""
#State private var isConnectionFailed: Bool = false
#State private var isLoginActive: Bool = false
#ObservedObject var viewModel = LoginViewModel()
var body: some View {
ScrollView(.vertical, showsIndicators: false) {
ZStack {
VStack {
VStack {
Image("Logo Registration")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 150)
Text("Welcome")
.bold()
.font(.system(size: 22))
.foregroundColor(Color("T1"))
.padding(.top)
Text("Sign in to continue")
.font(.system(size: 18))
.foregroundColor(Color("T1"))
.padding(.top, 8)
}
.padding()
.padding(.bottom)
VStack(spacing: 20) {
HStack {
Image("Call Us_Menu")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 35)
.padding(.leading, -10)
Divider()
.rotationEffect(Angle(degrees: 180))
.frame(height: 50)
Text("+88")
.foregroundColor(.gray)
.padding(.horizontal, 10)
Divider()
.rotationEffect(Angle(degrees: 180))
.frame(height: 50)
TextField("Mobile Number", text: self.$viewModel.mobileNumber)
}
.crTextFieldStyle(size: size, height: 50)
HStack {
Image("Password")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 35)
.padding(.leading, -10)
Divider()
.rotationEffect(Angle(degrees: 180))
.frame(height: 50)
SecureField("Password", text: self.$viewModel.password)
}
.crTextFieldStyle(size: size, height: 50)
}
HStack {
Text(self.errorMessage)
.font(.system(size: 12))
.foregroundColor(Color("T2"))
Spacer()
}
.frame(width: size.width/1.2)
HStack {
NavigationLink(
destination: ResetPasswordStepOneView()
.navigationBarHidden(isHidden: true)
) {
Text("Forgot Password?")
.foregroundColor(Color("T1"))
}
Spacer()
}
.padding(.bottom, 40)
.frame(width: size.width/1.2)
.font(.system(size: 14))
if self.viewModel.loginModel?.status == "ok" {
NavigationLink(
destination: ContentView()
.navigationBarHidden(isHidden: true)
.navigationBarBackButtonHidden(true),
isActive: $isLoginActive,
label: {
EmptyView()
}
)
}
Button(action: {
if self.viewModel.mobileNumber == "" || self.viewModel.password == "" {
self.errorMessage = "Mobile number or password is missing"
} else if Connectivity.isConnectedToInternet() {
self.viewModel.loading = true
self.errorMessage = ""
self.isLoginActive.toggle()
self.viewModel.fetchWithAF()
} else {
self.isConnectionFailed = true
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
self.isConnectionFailed = false
}
}
}) {
Text("SIGN IN")
}
.frame(width: size.width/1.2, height: 50)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color("B7"), lineWidth: 1)
)
.foregroundColor(Color("T2"))
Text("Or")
.padding()
NavigationLink(
destination: RegistrationView()
.navigationBarHidden(isHidden: true)
) {
Text("CREATE NEW ACCOUNT")
.foregroundColor(Color("T2"))
.bold()
}
Spacer()
}
.frame(width: size.width)
.padding(.bottom, 170)
if self.isConnectionFailed {
ConnectivityError()
}
}
}
}
}
LoginViewModel:
import Foundation
import SwiftUI
import Alamofire
class LoginViewModel: ObservableObject{
#Published var loginModel: LoginModel?
#Published var loading: Bool = false
#Published var isError: Bool = false
#Published var mobileNumber: String = ""
#Published var password: String = ""
#Published var isActive = false
func fetchWithAF() {
let registrationReq = LoginReqModel(phone: "+88" + self.mobileNumber, password: self.password)
let url = AppConstant.signin
let headers: HTTPHeaders = [
"Content-Type": "application/json"
]
AF.request(URL.init(string: url)!, method: .post, parameters: registrationReq, encoder: JSONParameterEncoder.default, headers: headers).responseJSON { (response) in
switch response.result {
case .success(_):
DispatchQueue.main.async {
do {
self.loginModel = try JSONDecoder().decode(LoginModel.self, from: response.data!)
if self.loginModel?.payload?.count ?? 0 > 0 {
let encoder = JSONEncoder()
if let encoded = try? encoder.encode(self.loginModel) {
let defaults = UserDefaults.standard
defaults.set(encoded, forKey: AppConstant.loginPayoad)
}
AppConstant.token = self.loginModel?.payload![0].accessToken ?? ""
}
self.loading = false
if self.loginModel?.status == "ok" {
self.isActive = true
UserDefaults.standard.set(self.mobileNumber, forKey: "Mobile")
UserDefaults.standard.set(self.password, forKey: "Password")
}
if self.loginModel?.status == "error" {
self.isError = true
}
} catch {
print("")
}
}
break
case .failure(let error):
print("working error \(error)")
break
}
}
}
}
Your viewModel is recreated every time the view reloads. Try changing it to:
#StateObject var viewModel = LoginViewModel()
StateObject (introduced in iOS 14) will ensure the object is only created once per view. ObservedObjects need to be owned by some parent view or class.

SwiftUI ActionSheet Picker

I'm trying to create in SwiftUI an action sheet that appears after pressing a button and allow the user to select and return an item throught a picker (like this https://imgur.com/a/IbS7swX).
Any hint on how to do it?
Thanks
struct ContentView: View {
init() {
UITableView.appearance().separatorColor = .clear
}
var inputArray = ["100","101","102"]
#State var slectedSegmant = "ActionSheet"
#State var slectedObj = "101"
#State var enableSheet = false
var test = false
var body: some View {
ZStack {
VStack(spacing: 10) {
Picker(selection: $slectedSegmant, label: Text("Segment")) {
Text("Alert").tag("Alert")
Text("ActionSheet").tag("ActionSheet")
}.pickerStyle(SegmentedPickerStyle())
.labelsHidden()
.padding(EdgeInsets.init(top: 50, leading: 10, bottom: 0, trailing: 10))
Text("Alert & Pickers")
.font(Font.system(size: 35, design: .rounded))
.fontWeight(.bold)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal)
List((0...50),id: \.self) { input in
ZStack {
HStack(spacing: 10) {
Image(systemName: "book")
.font(.title)
.padding(.leading, 10)
VStack(alignment: .leading, spacing: 5, content: {
Text("Simple")
Text("3 different buttons")
})
Spacer()
}.padding(.vertical)
.frame(maxWidth:.infinity)
.background(RoundedRectangle(cornerRadius: 10).foregroundColor(Color.white).shadow(radius: 1.5)
)
Button(action: {
self.enableSheet = true
}) {
Text("")
}
}
}.padding()
}.blur(radius: $enableSheet.wrappedValue ? 1 : 0)
.overlay(
$enableSheet.wrappedValue ? Color.black.opacity(0.6) : nil
)
if $enableSheet.wrappedValue {
GeometryReader { gr in
VStack {
VStack {
Text("PickerView")
.font(.headline)
.foregroundColor(.gray)
.padding(.top, 10)
Text("Prefered ContentHeight")
.padding(.top, 5)
Picker("test", selection: self.$slectedObj) {
Text("100").id("100")
Text("101").id("101")
Text("101").id("102")
}.labelsHidden()
}.background(RoundedRectangle(cornerRadius: 10)
.foregroundColor(Color.white).shadow(radius: 1))
VStack {
Button(action: {
debugPrint("Done Selected")
self.enableSheet = false
}) {
Text("Done").fontWeight(Font.Weight.bold)
}.padding()
.frame(maxWidth: gr.size.width - 90)
.background(RoundedRectangle(cornerRadius: 10)
.foregroundColor(Color.white).shadow(radius: 1))
}
}.position(x: gr.size.width / 2 ,y: gr.size.height - 200)
}
}
}.edgesIgnoringSafeArea(.all)
}
}
OUTPUT