Как обновить представление в зависимости от нажатия кнопки из другого представления в SwiftUI

#swiftui

#swiftui

Вопрос:

Я часто сталкиваюсь с такой ситуацией, но пока я не мог найти хорошего решения. Дело в том, что когда мое представление SwiftUI становится больше, я рефакторирую код, создавая другую структуру и вызывая структуру в соответствующем представлении. Допустим, я получил структуру A и произвел рефакторинг некоторого кода в структуре B, но как я могу обновить представление или вызвать функцию в структуре A в зависимости от нажатия кнопки в структуре B? Приведенный ниже код может помочь понять ситуацию:

 import SwiftUI

struct ContentView: View {
  @State var myText: String = "Hello World"
  @State var isActive: Bool = false
  var body: some View {
      VStack {
          Text(self.myText)
          AnotherStruct(isActive: $isActive)
      }
      .onAppear {
          if self.isActive == true {
              self.getApi()
          }
      }
  }

  func getApi() {
      print("getApi called")
      self.myText = "Hello Universe"
    }
  }

struct ContentView_Previews: PreviewProvider {
  static var previews: some View {
      ContentView()
  }
}

struct AnotherStruct: View {
  @Binding var isActive: Bool
  var body: some View {
      VStack {
          Button( action: {
              self.isActive.toggle()
          }) {
              Text("Button Tapped")
          }
      }
  }
}
  

Ответ №1:

Вот демонстрация возможного подхода к решению таких случаев — с разделенной ответственностью и делегированной активностью.

 struct ContentView: View {
    @State var myText: String = "Hello World"

    var body: some View {
        VStack {
            Text(self.myText)
            AnotherStruct(onActivate: getApi)
        }
    }

    func getApi() {
        print("getApi called")
        self.myText = "Hello Universe"
    }
}

struct AnotherStruct: View {
    let onActivate: () -> ()

//  @AppStorage("isActive") var isActive      // << possible store in defaults

    var body: some View {
        VStack {
            Button( action: {
        //      self.isActive = true
                self.onActivate()
            }) {
                Text("Button Tapped")
            }
        }
//      .onAppear {
//        if isActive {
//            self.onActivate()
//        }
//      }
    }
}