Swiftui Sheet Not Updating Variable

SwiftUI Sheet not updating variable

Create a binding with an optional workout. Nil will be the case that the sheet is not presented, assigning a workout to this variable displays the corresponding sheet.

struct WorkoutList: View {
private var workouts = workoutData
@State var selectedWorkout: Workout?

var body: some View {
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 20) {
ForEach(workouts) { workoutCard in
GeometryReader { geometry in
Button(action: { self.selectedWorkout = workoutCard }) {
WorkoutCardView(workout: workoutCard).rotation3DEffect(Angle(degrees: Double((geometry.frame(in: .global).minX - 30) / -30)), axis: (x: 0, y: 10, z: 0)).sheet(item: self.$selectedWorkout) { workout in
WorkoutDetails(workout: workout)
}
}
}.frame(width:246, height: 360)
}
}.padding(30)
}
}
}

SwiftUI sheet doesn't access the latest value of state variables on first appearance

You see value on time of sheet creation. If you want to track parent view state create sheet subview with binding to that state, like below. Binding will update subview when subview will appear.

Tested with Xcode 12 / iOS 14

Re-tested with Xcode 13.3 / iOS 15.4

struct DemoView: View {
@State var showDetails: Bool = false
var body: some View {
VStack {
Button(action: {
showDetails = true
}) {
Text("Show sheet")
}
}.sheet(isPresented: $showDetails){
SheetDetailView(flag: $showDetails)
}
}
}

struct SheetDetailView: View {
@Binding var flag: Bool
var body: some View {
VStack {
Text("showDetails: \(flag ? "yes" : "no")")
}
}
}

SwiftUI @State variable not updating view

Change this

ErrorView(alert: viewModel.$alert, error: viewModel.$error)

to this

ErrorView(alert: $viewModel.alert, error: $viewModel.error)

Tips

Almost always, you should move any variables to your View Model. For example you have email and password as @State variables in your view. It makes much more sense to move those to your View Model. Why? You may later need to access them inside of a function or method in your VM itself. It's much easier to handle that if the data is already there. In your view you'd access it as Text(viewModel.email) or Text(viewModel.password). However if you need to validate that, inside your view model, it'll be readily accessible.

SwiftUI not updating variable after async firebase call

SwiftUI views automatically trigger updates according to the state of their views. Because the Firebase calls are asynchronous, you cannot expect that a synchronous call to the fetch function will return with the correct result.

Instead, you need to update a Published value (on the main thread) that will then broadcast an update message to all subscribers of that value. SwiftUI automatically handles the subscribe mechanism with StateObject or ObservedObject and triggers a new request for the body of the view.

To get your code working with SwiftUI, adjust checkFriendRequest as follows:

Change this:

            if pendingFriendRequests[key] == true {
self.isFriend = 1
} else if pendingFriendRequests[key] == false {
self.isFriend = 2
}

To: (Because it triggers UI events and all UI must run on main thread)

          DispatchQueue.main.async {
if pendingFriendRequests[key] == true {
self.isFriend = 1
} else if pendingFriendRequests[key] == false {
self.isFriend = 2
}
}

In your view, change the VStack to:

      VStack {
if userData.isFriend == 1 {
//button for if returned 1
} else if userData.isFriend == 2 {
//button for if returned 2
} else {

}
}.onAppear() {
userData.checkFriendRequest(otherUserUID: otherUserUID)
}

SwiftUI: View not updating when Observed object changes from another file

There are many ways to have the viewModel changes reflected in different Views, the following is an example, where the main idea is to have one source of truth that you use in all the different Views:

declare @StateObject var viewModel = VariableSetupModel() in ContentView and
@EnvironmentObject var viewModel: VariableSetupModel in ContentNavView.

Pass viewModel from
ContentView to ContentNavView using .environmentObject(viewModel), that is, add this to ContentView, eg: VStack (alignment: .leading) {...}.environmentObject(viewModel)

Note, there is no need for VariableSetupModel to be a singleton, remove the static let shared = VariableSetupModel().

Note also, to have the viewModel available in SettingsView() use, SettingsView().environmentObject(viewModel)

Another approach is to pass a ObservedObject from one view to another.
For example:

declare @StateObject var viewModel = VariableSetupModel() in ContentView and

@ObservedObject var viewModel: VariableSetupModel in ContentNavView.

Pass viewModel from ContentView to ContentNavView using ContentNavView(viewModel: viewModel).

SwiftUI webview not updating with @State variable

try to use @Binding
for exemple:

struct WebView: View {
@Binding var siteUrl :String
var body: some View {
Text(siteUrl)
}
}

struct ContentView: View {
var siteArray = ["http://www.google.com","http://www.yahoo.com","http://www.amazon.com"]
@State private var siteUrl = "http://www.target.com"
@State private var showWebView = false

var body: some View {
ScrollView{
Text("Websites")
Button("Target") {
showWebView.toggle()
}
Button("Google") {
siteUrl = siteArray[1]
showWebView.toggle()
}
}
.sheet(isPresented: $showWebView) {
WebView(siteUrl: $siteUrl)

}
}
}

Sample Image

SwiftUI sheet never updated after first launch

In your .sheet you are passing the value of your ContentView @State to a new @State. So it will be independent from the ContentView.

To create a connection or a binding of your ContentView @State value, you should define your SheetView var as @Binding. With this edit you will pass the binding of your state value to your sheet view.

struct SheetView: View {
@Binding var i: Int

var body: some View {
Text("Hello \(i)")
}
}

struct ContentView: View {
@State var isPresented = false
@State var i: Int = 0

var body: some View {

List {
Button("0") {
self.i = 0
self.isPresented = true
}
Button("1") {
self.i = 1
self.isPresented = true
}
}.sheet(
isPresented: $isPresented,
content: {
SheetView(i: self.$i)
})
}
}


Related Topics



Leave a reply



Submit