1

is it possible to call a func of a View from outside.
I tried like this, but had no success.

@main
struct CallFromOutsideApp: App {
  var body: some Scene {
    WindowGroup {
      ContentView()
    }
  }
}

struct ContentView: View {
  var body: some View {
    VStack{
      SubView()
      Button("Call alterX in ContentView"){
        // How to call alterX in SubView????
      }
    }
    .padding()
  }
}

struct SubView: View {
  @State var x = "Status A"
  
  var body: some View {
    VStack{
      Text("Status: \(x)")
      Button("Call alterX in SubView"){ alterX()
      }
    }
    .padding()
  }
  
  func alterX(){
    x = "Status B"
  }
}


2
  • Next should be helpful : stackoverflow.com/a/65940114/14733292 Commented Feb 5, 2021 at 4:11
  • You try to bring interactive nature to SwiftUI reactive world. It does not work in that way. The most common schema is Action > ViewModel > View, ie. some action changes some view model and dependent view (observing that view model) reacts and updates corresponding parts. View model is any external dynamic source of truth. Commented Feb 5, 2021 at 5:58

1 Answer 1

3

EDIT

You shouldn't control SubView's @State from ContentView. Instead, put the @State in ContentView and pass it to a @Binding in SubView.

struct ContentView: View {
    @State var x = "Status A"
    var body: some View {
        VStack{
            
            SubView(x: $x) /// pass in the binding
            
            Button("Alter X in ContentView"){
                x = "Status B"
            }
        }
        .padding()
    }
}

struct SubView: View {
    @Binding var x: String
    
    var body: some View {
        VStack{
            Text("Status: \(x)")
            Button("Alter X in SubView") {
                x = "Status B"
            }
        }
        .padding()
    }
}

You could store SubView in a property. Like

struct ContentView: View {
  let subView = SubView()
  var body: some View {
    VStack{

      subView /// like this

      Button("Call alterX in ContentView"){
        subView.alterX() /// call it
      }
    }
    .padding()
  }
}

struct SubView: View {
  @State var x = "Status A"
  
  var body: some View {
    VStack{
      Text("Status: \(x)")
      Button("Call alterX in SubView"){ alterX()
      }
    }
    .padding()
  }
  
  func alterX(){
    x = "Status B"
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

thnx - interesting: in the second approach "alterX" gets called but the state change isn't reflected in the UI

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.