我正在做一个项目,其中SwiftUI和MapKit用于在Map上绘制注解。我的解决方案是能够绘制大约1k的注解,但我需要一个解决方案,可以处理至少10k没有滞后或性能问题。
我已经创建了一个示例代码,在Map上绘制一个红色圆圈。您可以通过按“Add”按钮添加注解。还有一个跟踪器类,用于跟踪注解渲染的次数。
import SwiftUI
import MapKit
struct MapAnnotation {
var id: Int
var location: CLLocationCoordinate2D
}
class Tracker {
var done = 0
static let shared = Tracker()
}
struct ContentView: View {
@State private var mapAnnotations: [MapAnnotation] = .init()
var body: some View {
ZStack {
Map() {
ForEach(mapAnnotations, id: \.id) { intensity in
Annotation("", coordinate: intensity.location, content: {
Circle()
.foregroundStyle(Color.red)
.frame(width: getWidth(intensity: intensity))
})
}
}
Button(action: {
print("Adding")
Tracker.shared.done = 0
mapAnnotations.append(.init(id: .random(in: 0 ... Int.max), location: .init(latitude: .random(in: -5 ... 5), longitude: .random(in: -5 ... 5))))
}, label: {
Text("Add")
.font(.title)
.foregroundStyle(Color.red)
})
}
}
private func getWidth(intensity: MapAnnotation) -> CGFloat {
Tracker.shared.done += 1
print(Tracker.shared.done)
return 10
}
}
#Preview {
ContentView()
}
字符串
运行上面的代码(Xcode 15.1,iOS 17.2 SDK)打印以下内容:
Adding
1
2
Adding
1
2
3
Adding
1
2
3
4
型
这表明每当引入新的注解时,系统都会重新渲染所有先前存在的注解。因此,当处理5000个注解的数据集并引入额外的注解时,整个5001个注解集都会进行渲染,从而导致延迟和性能问题。
有没有什么方法可以优化注解渲染以避免性能问题?
更新:
更改代码以批量添加注解:
import SwiftUI
import MapKit
struct MapAnnotation {
var id: Int
var location: CLLocationCoordinate2D
// Other Data
}
struct ContentView: View {
@State private var mapAnnotations: [MapAnnotation] = .init()
var body: some View {
ZStack {
Map() {
ForEach(mapAnnotations, id: \.id) { mapAnnotation in
Annotation("", coordinate: mapAnnotation.location, content: {
Circle()
.foregroundStyle(Color.red)
.frame(width: 10)
})
}
}
VStack {
Button(action: {
mapAnnotations.append(.init(id: .random(in: 0 ... Int.max), location: .init(latitude: .random(in: -5 ... 5), longitude: .random(in: -5 ... 5))))
}, label: {
Text("Add One")
.font(.title)
.foregroundStyle(Color.red)
})
Button(action: {
for _ in 0 ... 999 {
mapAnnotations.append(.init(id: .random(in: 0 ... Int.max), location: .init(latitude: .random(in: -5 ... 5), longitude: .random(in: -5 ... 5))))
}
}, label: {
Text("Add Many")
.font(.title)
.foregroundStyle(Color.red)
})
}
.background(Color.black)
}
}
}
#Preview {
ContentView()
}
型
我已经分析了仪器中的新代码,并发现了以下趋势:
的数据
它表明,当存在5k注解时,在主线程上再添加一个注解大约需要27秒,导致无响应。
大部分时间都花在MapKit [MKAnnotationView _metricsDidChange]
上,我怀疑我能优化它。
有什么建议吗?
1条答案
按热度按时间liwlm1x91#
群集注解或绘制自定义覆盖。
ForEach循环所有项目是正常的,而不是密集的。只有diff结果用于初始化新对象,如MKMapAnnotation,如果它正在初始化重复的注解,则注解标识可能有问题。
仅供参考SwiftUI“不呈现原生平台框架(AppKit和UIKit)提供的视图,如Web视图、媒体播放器和某些控件。”https://developer.apple.com/documentation/swiftui/imagerenderer