StateObject as parameter for another object in init()
Use computed property
struct Test: App {
@StateObject var user: User = User()
var authenticationHelper: AuthenticationHelper {
return AuthenticationHelper(user: user)
}
init() {
}
}
You can also use like this
struct Test: App {
@StateObject var user: User
var authenticationHelper: AuthenticationHelper
init() {
let user = User()
self._user = StateObject(wrappedValue: user)
self.authenticationHelper = AuthenticationHelper(user: user)
}
}
Initialize @StateObject with a parameter in SwiftUI
Here is a demo of solution. Tested with Xcode 12+.
class MyObject: ObservableObject {
@Published var id: Int
init(id: Int) {
self.id = id
}
}
struct MyView: View {
@StateObject private var object: MyObject
init(id: Int = 1) {
_object = StateObject(wrappedValue: MyObject(id: id))
}
var body: some View {
Text("Test: \(object.id)")
}
}
From Apple (for all those like @user832):
Initialize StateObject with another StateObject
Try the following
@main
struct DuneApp: App {
@StateObject var userManager: UserManager
@StateObject var appearancesStore: AppearancesStore
@StateObject var behavioursStore: BehavioursStore
init() {
let userManager = UserManager()
_userManager = StateObject(wrappedValue: userManager)
_appearancesStore = StateObject(wrappedValue: AppearancesStore(manager: userManager))
_behavioursStore = StateObject(wrappedValue: BehavioursStore(manager: userManager))
}
var body: some Scene {
WindowGroup {
AuthenticateView()
.environmentObject(userManager)
.environmentObject(appearancesStore)
.environmentObject(behavioursStore)
}
}
}
How to initialize a view with a stateobject as a parameter?
I can't fully reproduce your code without your definitions of Authenticator
and UsersViewModel
, but I got it to compile:
class UsersViewModel: ObservableObject {}
class Authenticator: ObservableObject {}
struct ProfileEditView: View {
@ObservedObject var viewModel: UsersViewModel
@StateObject var auth: Authenticator
@State var showingImageEditor: Bool = false
init(_ viewModel: ObservedObject<UsersViewModel>, _ auth: Authenticator) {
_viewModel = viewModel
_auth = StateObject(wrappedValue: auth)
UITableView.appearance().backgroundColor = UIColor.clear
UITableViewCell.appearance().selectionStyle = .none
}
var body: some View {
Text("something")
}
}
These are the key changes:
init(_ viewModel: ObservedObject<UsersViewModel>, _ auth: Authenticator) {
_viewModel = viewModel
_auth = StateObject(wrappedValue: auth)
If you don't understand my changes you should google
"swift property wrappers"
to get a better understanding of what property wrappers are and how to use them.
SwiftUI: How to initialize a new StateObject in a parent view?
As mentioned in the comments already, the route you probably want to take is reseting the state within the same WorkoutManager
. You wouldn't be able to assign a new object to a @StateObject
anyway -- you'll end up with compiler errors because of the View
's immutable self
.
Secondly, I'd suggest that you probably don't want to rely on the Button
in your WorkoutView
to do this. For example, if the user dismissed the sheet
by swiping, that wouldn't get called. Instead, you could listen for the sheet
's state in onChange
(another method would be using the onDismiss
parameter of sheet
):
class WorkoutManager: ObservableObject {
var workout: HKWorkout?
func resetState() {
//do whatever you need to do to reset the state
print("Reset state")
}
}
struct ContentView: View {
@StateObject var workoutManager = WorkoutManager()
@State var showingWorkoutView = false
var body: some View {
Button {
showingWorkoutView.toggle()
} label: {
Text("Start Workout")
}
.sheet(isPresented: $showingWorkoutView) {
WorkoutView(showingWorkoutView: $showingWorkoutView)
}
.onChange(of: showingWorkoutView) { newValue in
if !newValue {
workoutManager.resetState()
}
}
}
}
struct WorkoutView: View {
@EnvironmentObject var workoutManager: WorkoutManager
@Binding var showingWorkoutView: Bool
var body: some View {
Text("Workout Started")
.padding()
Button {
showingWorkoutView.toggle()
} label: {
Text("End Workout")
}
}
}
Need data to initialize a StateObject
I believe you are trying to use these properties inside a View
.
To solve your problem, you can simply split your code in two different views, where in the first one you define the SettingsStore
instance, then you use it to initialise the Matrix
instance of the second view.
Like this:
struct FirstView: View {
@State private var settingsStore = SettingsStore()
var body: some View {
SubView(settingsStore: $settingsStore, matrix: Matrix(d: settingsStore.d))
}
}
struct SubView: View {
@Binding var settingsStore: SettingsStore
@StateObject var matrix: Matrix
var body: some View {
Text(matrix.d)
}
}
How to initialize a View by observing @StateObject from other View
You should have one source of truth for your viewModel
.
Create your viewModel
as a @StateObject
in ContentView
and pass it to AddEmployeeView
and AllEmployeesView
.
In order to do that, declare:
@ObservedObject var viewModel: EmployeeViewModel
in both AddEmployeeView
and AllEmployeesView
. Then pass in viewModel
from ContentView
like this:
AddEmployeeView(viewModel: viewModel)
and
AllEmployeesView(viewModel: viewModel)
That way, all three of your views will be working from the same viewModel
which keeps everything in sync.
Related Topics
A Method Without Parameters Is Calling for an Argument
How to Read Ansi Escape Code Response Value in Swift
Exc Bad Access After Coding Signing
Initializer for Conditional Binding Must Have Optional Type, Not '[String:Any]'
How to Pass Closure as a Parameter in Perform(Selector, Withobject)
Hiding Dividers in Nssplitview
Node.Physicsbody.Joints Downcasting Error
How to Increment Exponentially in Swift
Elegant 'Bounded' Methodology in Swift
App Window on Top of All Windows Including Others App Windows
Contextual Member Has No Associated Value in Swift 3
Value of Optional Type 'Nsurl' Not Unwrapped; Did You Mean to Use '!' or ''
How to Take a Substring to the First Index of a Character
Learning Swift: Expressions Are Not Allowed at the Top Level
How to Stop an Infinitely Rotating Image? and How Does One Implement Removeallanimations
Swift Check If Value Is of Type Array (Of Any Type)
Resizing Large Resolution Images Producing 1000X1000 Pixels Size When Size Is Set to 500X500 Pixels