I just found some strange behaviour of SwiftUI's UIViewRepresentable. I'm not sure if this is a bug, or my mistake in understanding SwiftUI. I've made small reproduction to show the problem.
I created UIViewRepresentable for MKMapView:
import SwiftUI
import MapKit
struct UIMap: UIViewRepresentable {
func makeUIView(context: Context) -> MKMapView {
let map = MKMapView(frame: .zero)
map.delegate = context.coordinator
return map
}
func updateUIView(_ map: MKMapView, context: Context) {
print("Change!")
}
func makeCoordinator() -> UIMapCoordinator {
return UIMapCoordinator(self)
}
class UIMapCoordinator: NSObject, MKMapViewDelegate {
var parent: UIMap
init(_ parent: UIMap) {
self.parent = parent
}
}
}
Then I create really small wrapper for this representable:
import SwiftUI
struct MapWrapper: View {
var body: some View {
UIMap()
}
}
Finally I'm using it in ContentView:
import SwiftUI
struct ContentView: View {
@State private var showSheet = false
@State private var showButton = true
var body: some View {
ZStack(alignment: .bottom){
MapWrapper()
HStack{
if showButton {
Button(action: { showSheet = true }){
Text("Show Sheet")
}
.foregroundColor(.yellow)
}
Spacer()
Button(action: { showButton = !showButton }){
Text("Toggle Button")
}
.foregroundColor(.yellow)
}
}
.sheet(isPresented: $showSheet) {
Text("Sheet content")
}
}
}
I have two clickable elements in ContentView - one for opening a sheet, and another for hiding button (just to see state change). Opening sheet (changing showSheet
to true
) causes updateUIView
being called ("Change!" is printed in debug console), while changing showButton
doesn't do that. It looks like opening sheet changes state of MapWrapper
(?). Is this behaviour correct?