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
fromContentView
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)
}
}
}
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
How to Hash a String to Sha512 in Swift
Accessibility (Voice Over) with Sprite Kit
Uiprogressview Progress Update Very Slow Within Alamofire (Async) Call
Nsdateformatter Detect 24-Hour Clock in Os X and iOS
Alamofire 5 Upload Encodingcompletion
Closures Return Value (Previously Completionblock)
Module Compiled with Swift 4.0 Cannot Be Imported in Swift 3.0.2
Uilabel Subclass Appearance in Storyboard
Glkit VS. Metal Perspective Matrix Difference
Create Generic Delegate for Class
Nspopover to Start in a Detached State
Swift Get Nsdata of a Video from Photos Library
How to Keep a Reference to Another Object in the Parameters of the Class
Swiftui, Shadow Only for Container
Formsheet iOS 8 Constraints Are Same as Iphones Constraints
App Crashes from IPA File But Runs Fine from Xcode
Uicollectionview Autosize and Dynamic Number of Rows
In Swift, Can You Find All Types in a Module That Adhere to a Specific Protocol