habibiboss
habibiboss

Reputation: 411

Swift - How to access @Published var from func outside of view?

I'm trying to remove the logic from the view, while keeping the benefits of SwiftUI. Idea 1 works but it makes use of an extra variable than I would want to. Idea 2 gives error: Property wrappers are not yet supported on local properties. The view should return "bar". What is the best way of making this work? Many thanks.

import Combine
import Foundation
import SwiftUI

// Model

enum Model: String, RawRepresentable {

    case foo = "foo"
    case bar = "bar"
}

// State

var data1: String = Model.foo.rawValue

class State: ObservableObject {

    @Published internal var data2: String = data1
}

// Logic

func logic() {

// Idea 1: OK

    //data1 = Model.bar.rawValue
    //print(State().data2)

// Idea 2: Error Property wrappers are not yet supported on local properties

    @EnvironmentObject private var state: State
    state.data2 = Model.bar.rawValue
    print(state.data2)
}

// View

struct bar: View {

    @EnvironmentObject private var state: State

    internal var body: some View {

        logic()
        return Text(verbatim: self.state.data2)
    }
}

Upvotes: 2

Views: 4501

Answers (1)

Rob Napier
Rob Napier

Reputation: 299355

If you want a function to have access to a view's state, pass the state:

func logic(state: State) {
    state.data2 = Model.bar.rawValue
    print(state.data2)
}

But what you've done here is an infinite loop. Modifying a view's state causes the view to be re-rendered. So every time the view is rendered, it modifies its state and forces it to be rendered again. That will never resolve. What you may mean here is to change the state when the view first appears, in which case you'd call logic this way:

struct Bar: View {

    @EnvironmentObject private var state: State

    internal var body: some View {
        Text(verbatim: state.data2)
            .onAppear{ logic(state: self.state) }
    }
}

Upvotes: 4

Related Questions