SwiftUI 更新地图区域导致有关修改状态的警告

2024-02-13

我有一个使用 iOS 14 中新的 SwiftUI Map 的项目

我希望能够动态更新地图中心的位置。

当您点击“缩放”按钮,然后点击“位置”按钮时,地图可以正常工作并重新以伦敦为中心。

但是,如果您只是点击位置按钮,它会重新以伦敦为中心,但会引发有关 ViewState 的警告。

我不知道导致此问题的原因以及如何解决它。

struct ContentView: View {
    @State private var region = MKCoordinateRegion(
        center: CLLocationCoordinate2D(
            latitude: 25.7617,
            longitude: 80.1918
        ),
        span: MKCoordinateSpan(
            latitudeDelta: 10,
            longitudeDelta: 10
        )
    )

    var body: some View {
        VStack {
            Map(coordinateRegion: $region)
            Button("zoom") {
                withAnimation {
                    region.span = MKCoordinateSpan(
                        latitudeDelta: 100,
                        longitudeDelta: 100
                    )
                }
            }
            Button(action: {
                withAnimation {
                    region = MKCoordinateRegion(center: CLLocationCoordinate2D(
                                                    latitude: 51.507222,
                                                    longitude: -0.1275),
                                                span: MKCoordinateSpan(
                                                    latitudeDelta: 0.5,
                                                    longitudeDelta: 0.5))
                }
            }) {
                Image(systemName: "location.fill")
                    .frame(width: 44, height: 44, alignment: .center)
                    .foregroundColor(.black)
                    .background(Color(.white))
            }
            .buttonStyle(PlainButtonStyle())
            .clipShape(Circle())
            .shadow(color: .black.opacity(0.5), radius: 1.0, x: 0.0, y: 2.0)
        }
    }
}

这是那些会让你彻底发疯的错误之一,直到你接受它的含义正是它所说的:runtime: SwiftUI: Modifying state during view update, this will cause undefined behavior.该按钮位于视图中,当您按下它时,您正在更新视图并尝试修改它。解决方案是让此类修改后的数据来自视图结构之外。

我创建了一个类来保存地图坐标:

import Foundation
import MapKit

class Coordinates: ObservableObject {
    public static let shared = Coordinates()
    @Published var region: MKCoordinateRegion
    
    init() {
        self.region = MKCoordinateRegion(
        center: CLLocationCoordinate2D(
            latitude: 25.7617,
            longitude: 80.1918
        ),
        span: MKCoordinateSpan(
            latitudeDelta: 10,
            longitudeDelta: 10
        )
    )
    }
}

然后我修改了ContentView接受数据:

struct ContentView: View {
    @ObservedObject var coordinates = Coordinates.shared
    
    var body: some View {
        VStack {
            Map(coordinateRegion: $coordinates.region)
            Button("zoom") {
                withAnimation {
                    coordinates.region.span = MKCoordinateSpan(
                        latitudeDelta: 100,
                        longitudeDelta: 100
                    )
                }
            }
            Button(action: {
                withAnimation {
                    coordinates.region = MKCoordinateRegion(center: CLLocationCoordinate2D(
                                                    latitude: 51.507222,
                                                    longitude: -0.1275),
                                                span: MKCoordinateSpan(
                                                    latitudeDelta: 0.5,
                                                    longitudeDelta: 0.5))
                }
            }) {
                Image(systemName: "location.fill")
                    .frame(width: 44, height: 44, alignment: .center)
                    .foregroundColor(.black)
                    .background(Color(.white))
            }
            .buttonStyle(PlainButtonStyle())
            .clipShape(Circle())
            .shadow(color: .black.opacity(0.5), radius: 1.0, x: 0.0, y: 2.0)
        }
    }
}

您不必完全按照这种方式进行操作,但您需要牢记构建 SwiftUI 所依据的 MVVM 原则,并将事实来源与视图分开。我会跑过Apple 的 SwiftUI 教程 https://developer.apple.com/tutorials/swiftui如果你还没有,然后Paul Hegarty 的 CS193p 课程 https://cs193p.sites.stanford.edu真正感受它是如何运作的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SwiftUI 更新地图区域导致有关修改状态的警告 的相关文章

随机推荐

  • 使用和不使用 Set 关键字之间的类型差异

    我刚刚解决了一个问题 我将 Set 关键字放在定义行中 但我想知道的是 为什么 基本上 我正在这样做 Dim startCell iCell as Range For Each iCell in Range whatever If iCel
  • 什么是*确定性并发*?

    我听说有3种并发 确定性并发 消息传递并发 共享状态并发 我知道 2 演员模型 和 3 通用线程 但不知道 1 那是什么 确定性并发是一种并发编程模型 在此模型中编写的程序具有以下属性 对于给定的一组输入 程序的输出值对于任何执行计划都是相
  • C++ typedef 类的使用

    为什么要使用一个typedef class Name 我在IBM C 文档 http publib boulder ibm com infocenter comphelp v7v91 index jsp topic com ibm vacp
  • powershell 鼠标移动不会阻止空闲模式

    System Windows Forms Cursor Position New Object System Drawing Point pos X pos Y 1 System Windows Forms Cursor Position
  • OpenCV 全屏窗口

    我正在尝试使用 opencv 2 3 创建一个全屏窗口 但它不起作用 但我记得 它应该起作用 代码非常简单 cvNamedWindow 名称 CV WINDOW FULLSCREEN 我也尝试设置窗口属性 cvSetWindowProper
  • AWS API Gateway DynamoDB GetItem 没有排序键?

    我有一个 Dynamodb 表 其中包含以下内容 primary key S series sort key S type of brokers title S Types Of Brokers primary key S series s
  • Jquery Datatables - 使整行成为链接

    这也许很简单 但似乎无法弄清楚 使用 jquery 数据表如何使每一行可单击以链接到普通页面 因此 如果有人将鼠标悬停在任何一行上 则整行将突出显示并可单击 并链接到我希望它在单击时链接到的任何网址 我用过fnDrawCallbackjQu
  • Oracle 变异触发器

    我正在编写一个简单的触发器 它应该只发送一条消息 其中包含更新的行数以及性别的旧值和性别的更新值 然而 当我运行更新时 我收到错误 表明表正在发生变化 并且表可能无法看到它 但我不确定为什么 trigger create or replac
  • 如何设置 Pyomo 求解器超时?

    如何设置 Pyomosolve 方法的超时 更具体地说 告诉 pyomo 在 x 秒后 返回当前找到的最优解 所以我能够通过 pyomo 文档找到答案 我认为分享会有所帮助 设置 Pyomo 的超时时间solve method solver
  • 非对称密钥容器的相互转换(例如:X.509、PGP、OpenSSH)

    非对称加密密钥基本上可以在主要密钥容器格式之间相互转换吗 例如 我可以将 X 509 密钥文件转换为 PGP 或 OpenGPG 密钥文件吗 并且 假设答案是肯定的 以任何格式保存一对密钥并转换为该场合所需的任何容器文件格式是否 安全中立
  • 如何在emacs语义中包含标准jdk库?

    我使用的是 Emacs 23 2 这是我加载语义的方式 setq semantic default submodes global semantic idle scheduler mode global semanticdb minor m
  • R中glmnet中的岭回归;使用 glmnet 包计算不同 lambda 值的 VIF

    我有一组多重共线性变量 我正在尝试使用岭回归来解决这个问题 我正在使用glmnetR 中的包 alpha 0 用于岭回归 library glmnet 我有一系列 lambda 值 并且我通过 cv glmnet 选择最佳 lambda 值
  • ListView 列的最小宽度

    我怎样才能指定MinWidthWPF 中的 Listview 列 此代码使用 Thumb 控件 它将阻止用户仅将标题拖动到指定的宽度 将其添加到您的 WPF 中
  • 如何在 React 中实现 Cloudinary 上传小部件?

    我正在尝试在我的 React 应用程序中使用 Cloudinary 上传小部件 但我遇到了问题 运行项目时 上传小部件会立即出现 但是当关闭并再次打开时 应用程序崩溃并显示以下消息 widget open 不是一个函数 Note 上传工作正
  • 如何使用异步回调进行同步操作?

    如何用异步函数进行同步操作 class MyClass static let shared MyClass let operationQueue OperationQueue let dispatchGroup DispatchGroup
  • 隐式转换的 gcc 警告标志

    我最近遇到了一个与下一个类似的错误 double getSomeValue return 4 0 std string str str getSomeValue 正如您所看到的 很容易发现问题 但在大型代码库中getSomeValue 与调
  • 如何在CSS中动态调整图像大小?

    我有一个简单的 html css 页面 上面有 3 个图像 我试图根据浏览器窗口的大小调整页面大小 现在 我在一个 div 中有 3 个图像 其高度设置为周围容器的百分比 并且图像设置为 height 100 和 width auto 现在
  • 在 Ruby 中向类添加实例变量

    如何将实例变量添加到已定义的类中runtime 然后从类外部获取并设置其值 我正在寻找一种元编程解决方案 它允许我在运行时修改类实例 而不是修改最初定义该类的源代码 一些解决方案解释了如何在类定义中声明实例变量 但这不是我要问的 Ruby
  • WinDbg——TraceListener 和饱和线程池

    我有一个多线程 NET Windows 服务 它间歇性地挂起 可能每两周 24 7 运行一次 当发生挂起时 线程池完全饱和 因为对我们的自定义跟踪侦听器的调用由于某种原因开始阻塞 根据 Windbg 的说法 有问题的代码中没有任何锁 也没有
  • SwiftUI 更新地图区域导致有关修改状态的警告

    我有一个使用 iOS 14 中新的 SwiftUI Map 的项目 我希望能够动态更新地图中心的位置 当您点击 缩放 按钮 然后点击 位置 按钮时 地图可以正常工作并重新以伦敦为中心 但是 如果您只是点击位置按钮 它会重新以伦敦为中心 但会