title: How to show/reuse the same view (Alert) in SwiftUI from all ViewModels in case of an error/message?
body: <p>I have been trying to reuse an <code>Alert</code> from a <code>BaseView</code> (SwiftUI) that can be shown by all View Models in my project so I can avoid boilerplate code.</p>
  <p>For this I created two Views (<code>BaseView</code> and <code>BaseLoginView</code>) and two View Models (<code>BaseViewModel</code> and <code>LoginViewModel</code>)</p>
  <p>I realized that you just can't create a <code>BaseViewModel</code> and implement <code>ObservableObject</code> because all <code>@Published</code> variables on the child ViewModel will not fire any event so it seems that the <code>ObservableObject</code> interface must be implemented on the final ViewModel, which in this case is <code>LoginViewModel</code>.</p>
  <p>But this leads to another problem: the <code>BaseView</code> this way can't have an <code>@ObservedObject var baseViewModel: BaseViewModel</code> because the <code>BaseViewModel</code> doesn't conform to <code>ObservableObject</code>. And the <code>@ObservedObject</code> is needed to access the boolean bindings with <code>$</code>.</p>
  <p>This is what I a tried so far:</p>
  <h3>1 - <code>BaseView</code></h3>
  <pre class="lang-swift prettyprint-override"><code>struct BaseView&lt;Content: View&gt;: View {
  
      @ObservedObject var baseViewModel: BaseViewModel
  
      let content: Content
  
      init(vm: BaseViewModel, @ViewBuilder content: () -&gt; Content) {
          self.baseViewModel = vm
          self.content = content()
      }
  
      var body: some View {
          VStack {
              content
          }
         .alert(isPresented: self.$baseViewModel.showMessage) {
             Alert(title: Text(self.baseViewModel.messageTitle), message: Text(self.baseViewModel.messageText), dismissButton: .default(Text(&quot;Okay&quot;)))
         }
      }
  }
  </code></pre>
  <h3><code>LoginView</code> -&gt; Creates View Model and passes it to base View</h3>
  <pre class="lang-swift prettyprint-override"><code>import SwiftUI
  
  struct LoginView: View {
  
      @ObservedObject var loginViewModel: LoginViewModel
  
      @State private var username: String = &quot;&quot;
      @State private var password: String = &quot;&quot;
  
      let textFieldHeight = CGFloat(60)
      let textFieldPadding = CGFloat(15)
  
      init() {
          self.loginViewModel = LoginViewModel()
      }
  
      var body: some View {
  
          ZStack {
              NavigationView {
                  BaseView(vm: self.loginViewModel) {
                      VStack(alignment: .leading, spacing: 20) {
                          Text(self.loginViewModel.myTest)
                      }
                      Button(action: {
                          self.loginViewModel.login()
                      }) {
                          Text(&quot;Login&quot;)
                      }
                  }.navigationBarTitle(&quot;&quot;, displayMode: .inline)
              }
          }
      }
  }
  </code></pre>
  <h3><code>BaseViewModel</code></h3>
  <pre class="lang-swift prettyprint-override"><code>import Foundation
  
  class BaseViewModel : ObservableObject {
  
      @Published var showMessage: Bool = false
      @Published var messageTitle : String = &quot;&quot;
      @Published var messageText : String = &quot;&quot;
  
      public func showMessage(title: String, text: String) {
         self.messageTitle = title
         self.messageText = text
         self.showMessage = true
      }
  }
  </code></pre>
  <h3><code>LoginViewModel</code></h3>
  <pre class="lang-swift prettyprint-override"><code>import Foundation
  
  class LoginViewModel : BaseViewModel {
  
      @Published var myTest : String = &quot;Hello&quot;
  
      func login() {
          
          DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
              self.myTest = &quot;Bye&quot;
  //            self.showMessage(title: &quot;Invalid Data&quot;, text: &quot;Please fill all fields!&quot;)
          }
      }
  }
  </code></pre>
  <p>My <code>ContentView</code> that I created in a new project:</p>
  <pre class="lang-swift prettyprint-override"><code>import SwiftUI
  
  struct ContentView: View {
      var body: some View {
          //Text(&quot;Hello, World!&quot;)
          LoginView()
      }
  }
  
  struct ContentView_Previews: PreviewProvider {
      static var previews: some View {
          ContentView()
      }
  }
  </code></pre>
  <p>The problem is if I update the <code>showMessage</code> it works but changing only the <code>myTest</code> string to &quot;Bye&quot; doesn't update the view. It will only update if I also update a value that is published in the <code>BaseViewModel</code>. Why is that?</p>
  <p>How can I solve this problem and avoid boilerplate code?</p>