我想要
这可能吗?
MapViewEnvironment.swift
class MapViewEnvironment: ObservableObject {
@Published var value1 = "aaa"
@Published var currentMapCompany = "apple"
}
MapViewProtocol.swift
protocol MapViewProtocol {
func aaa()
func bbb()
}
AppleMapView.swift
struct AppleMapView: UIViewRepresentable, MapViewProtocol {
func aaa() { print("AppleMapView - aaa") }
func bbb() { print("AppleMapView - bbb") }
}
GoogleMapView.swift
struct GoogleMapView: UIViewRepresentable, MapViewProtocol {
func aaa() { print("GoogleMapView - aaa") }
func bbb() { print("GoogleMapView - bbb") }
}
CommonMapView.swift
struct CommonMapView: View {
@EnvironmentObject var mapViewEnvironment: MapViewEnvironment
@State var cancellable = Set<AnyCancellable>()
@State var currentMapView: AnyView? // <-- correct?
func choiceView() -> some View {
switch mapViewEnvironment.currentMapCompany {
case "apple":
currentMapView = AnyView(AppleMapView()) // Modifying state during view update, this will cause undefined behavior.
default:
currentMapView = AnyView(GoogleMapView())
}
return currentMapView
}
var body: some View {
choiceView().onAppear {
self.mapViewEnvironment.$value1
.filter { $0 == "aaa" }
.sink { _ in currentMapView.aaa() } // error
.store(in: &self.cancellable)
self.mapViewEnvironment.$value1
.filter { $0 == "bbb" }
.sink { _ in currentMapView.bbb() } // error
.store(in: &self.cancellable)
}
}
}
ContentView.swift
struct ContentView: View {
@EnvironmentObject var mapViewEnvironment: MapViewEnvironment
var body: some View {
VStack{
Button(action: { self.mapViewEnvironment.value1 = "aaa" }) { Text("set aaa") }
Button(action: { self.mapViewEnvironment.value1 = "bbb" }) { Text("set bbb") }
CommonMapView()
}
}
}
答案 0 :(得分:0)
自我答案。
我找到了另一种方法并更改了某些类。
ContentView.swift
struct ContentView: View {
@EnvironmentObject var mapViewEnvironment: MapViewEnvironment
var body: some View {
VStack {
Button(action: { self.mapViewEnvironment.value1 = "aaa" }) { Text("set aaa") }
Button(action: { self.mapViewEnvironment.value1 = "bbb" }) { Text("set bbb") }
Button(action: { self.mapViewEnvironment.currentMapCompany = "apple" }) { Text("set apple") }
Button(action: { self.mapViewEnvironment.currentMapCompany = "google" }) { Text("set google") }
CommonMapView()
}
}
}
CommonMapView.swift
struct CommonMapView: View {
@EnvironmentObject var mapViewEnvironment: MapViewEnvironment
var body: some View {
ZStack {
if mapViewEnvironment.currentMapCompany == "apple" {
AppleMapView()
} else {
GoogleMapView()
}
}
}
}
AppleMapView.swift
struct AppleMapView: UIViewRepresentable {
@EnvironmentObject var mapViewEnvironment: MapViewEnvironment
func makeUIView(context: Context) -> MKMapView {
let view = MKMapView()
view.mapType = .standard
willAppear(context)
return view
}
...
func makeCoordinator() -> AppleMapView.Coordinator {
return Coordinator()
}
static func dismantleUIView(_ uiView: MKMapView, coordinator: AppleMapView.Coordinator) {
coordinator.cancellable.removeAll()
}
final class Coordinator {
var cancellable = Set<AnyCancellable>()
}
}
extension AppleMapView: MapViewProtocol {
func willAppear(_ context: Context) {
mapViewEnvironment.$value1.filter { $0 == "aaa" }.sink { _ in self.aaa() }.store(in: &context.coordinator.cancellable)
mapViewEnvironment.$value1.filter { $0 == "bbb" }.sink { _ in self.bbb() }.store(in: &context.coordinator.cancellable)
}
func aaa() { print("AppleMapView - aaa") }
func bbb() { print("AppleMapView - bbb") }
}