Почему SwiftUI Map изменяет состояние своей вызывающей структуры, если фрейм не назначен?
Настраивать:
Мое приложение использует SwiftUI, по сути, как
struct MapViewSWUI: View {
@Binding private var show_map_modal: Bool
@State private var region: MKCoordinateRegion
//…
init(show_map_modal: Binding<Bool>) {
self._show_map_modal = show_map_modal
self.region = // Some computed region
//…
var body: some View {
//…
Map(coordinateRegion: $region)
.frame(width: 400, height: 300) // Some frame for testing
}
}
Используя этот код, я могу без проблем показать карту модально.
Проблема:
Если я прокомментирую.frame
модификатор просмотра, я получаю ошибку времени выполнения
Modifying state during view update, this will cause undefined behavior.
Вопрос:
Почему в моем случае требуется установитьframe
дляMap
? Это руководство делает это, адокументы Apple — нет. Как это сделать правильно?
PS:
Я прочитал этот ответ на аналогичный вопрос и попытался поймать ошибку с помощью точки останова во время выполнения, но ничего интересного не показывает:
Я нашел ответ на другие вопросы, связанные с той же ошибкой, но здесь это не применимо.
РЕДАКТИРОВАТЬ:
Обходной путь найден, но не понят:
Моя карта представлена модально из другого вида. Этот вид имеетstate var
который управляет презентацией:
@State private var show_map_modal = false
Тело представления состоит из нескольких представлений иfullScreenCover
модификатор представления применяется кHStack
:
var body: some View {
HStack {
// …
}
.fullScreenCover(isPresented: $show_map_modal) {
MapViewSWUI(show_map_modal: $show_map_modal, itemToBeDisplayed: viewItem)
.ignoresSafeArea(edges: [.leading, .trailing])
}
}
Если карта представлена таким образом, ошибка времени выполнения не возникает.
Однако, если я включу (как это делалось до сих пор).top
или.bottom
в наборе краев ошибка времени выполненияModifying state during view update
поднят .
Буду рад любому намеку на причину.
1 ответ
Я предполагаю, что ошибка связана вовсе не с фреймом, а с обновлением региона после представления листа.
Как вы можете видеть в моем коде, я обновляю регион через 3 секунды после представления Seet. Затем появляется ошибка.
Может ли это происходить в вашем коде?
struct ContentView: View {
@State private var show_map_modal = false
var body: some View {
Button {
show_map_modal.toggle()
} label: {
Text("Show me the map!")
}
.sheet(isPresented: $show_map_modal) {
MapViewSWUI(show_map_modal: $show_map_modal)
}
}
}
struct MapViewSWUI: View {
@Binding private var show_map_modal: Bool
@State private var region: MKCoordinateRegion
init(show_map_modal: Binding<Bool>) {
self._show_map_modal = show_map_modal
self.region = MKCoordinateRegion(
center: CLLocationCoordinate2D(
latitude: 51.507222,
longitude: -0.1275),
span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)
)
}
var body: some View {
VStack(alignment: .trailing) {
Button("Done") {
show_map_modal.toggle()
}
.padding(10)
Map(coordinateRegion: $region)
}
// .frame(width: 400, height: 300) // Some frame for testing
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
self.region = MKCoordinateRegion(
center: CLLocationCoordinate2D(
latitude: 31.507222,
longitude: -1.1275),
span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)
)
}
}
}
}