我在 SwiftUI 中使用 UIKit MKMapView 來獲得更多功能。我通過系結將地圖區域傳遞給 UIViewRepresentable,因此我可以從使用該 MKMapView 的 SwiftUI 視圖更新 UIKit 視圖。問題是我在地圖頂部有一個按鈕,負責將地圖居中重新定位到用戶位置,但是每次地圖區域發生變化時,updateUIView功能都會觸發,并且地圖會自行居中,從而導致地圖被卡住是因為每當我移動地圖(即縮放、拖動、旋轉)時,地圖都會以自身為中心。
我怎樣才能有條件地檢查按鈕是否被點擊 - 然后才使地圖居中?
更新UIView:
func updateUIView(_ uiView: MKMapView, context: Context) {
if let userLocation = uiView.annotations.first(where: { $0 is MKUserLocation }) {
uiView.setRegion(MKCoordinateRegion(center: userLocation.coordinate, span: MapDetails.defaultSpan), animated: true)
} // this gets triggered everytime map region changes.
}
UIViewRepresentable:
struct MapView: UIViewRepresentable {
@Binding var mapRegion: MKCoordinateRegion
@Binding var locations: [Location]
...
}
主 SwiftUI 視圖(我使用 MKMapView 的地方):
struct ExploreView: View {
@StateObject private var viewModel = MapViewModel()
@State private var didAppearOnce = false
@ViewBuilder
var body: some View {
NavigationView {
ZStack {
MapView(mapRegion: $viewModel.mapRegion, locations: $viewModel.locations)
.accentColor(.pink)
...
}
所以我的問題是,有沒有辦法有條件地檢查按鈕是否被按下,然后才將地圖居中updateUIView?
uj5u.com熱心網友回復:
留空updateUIView,然后在您的viewModel
import Combine
class MapViewModel:ObservableObject {
@Published var buttonCenterPressed = false
var buttonCancellable: AnyCancellable?
}
在引數中使用mapViewUIViewRepresentable添加訂閱者makeUIView
struct MapView: UIViewRepresentable {
@Binding var mapRegion: MKCoordinateRegion
@Binding var locations: [Location]
var viewModel: MapViewModel
...
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView(frame: .zero)
mapView.showsUserLocation = true
setSubscriber(mapView)
return mapView
}
func updateUIView(_ mapView: MKMapView, context: Context) {}
func setSubscriber(_ mapView: MKMapView){
viewModel.buttonCancellable = viewModel.$buttonCenterPressed.sink(receiveValue: { _ in
if let userLocation = mapView.annotations.first(where: { $0 is MKUserLocation }) {
mapView.setRegion(MKCoordinateRegion(center: userLocation.coordinate, span: MapDetails.defaultSpan), animated: true)
}
})
}
將viewModel引數添加到MapView
struct ExploreView: View {
@StateObject private var viewModel = MapViewModel()
@State private var didAppearOnce = false
@ViewBuilder
var body: some View {
NavigationView {
ZStack {
MapView(mapRegion: $viewModel.mapRegion, locations: $viewModel.locations, viewModel: viewModel)
.accentColor(.pink)
...
}
現在您可以實作動作居中按鈕并將MapView更新。
Button(action: {
viewModel.buttonCenterPressed.toggle()
}, label: {
Text("Center")
})
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/515416.html
