【问题标题】:SwiftUI why a variable is passed on other views automatically?SwiftUI 为什么会自动将变量传递给其他视图?
【发布时间】:2021-09-25 17:18:02
【问题描述】:

每次更改 ContentView 中的“位置”变量时,我的 MapView“注释”变量如何更新?我用谷歌搜索了 swift 数组是一种值类型,我什至不需要在“注释”上使用绑定并绑定到“位置”,以便“注释”了解“位置”何时发生变化,这是为什么呢?

import SwiftUI
import MapKit

struct ContentView: View {
    @State var centerCoordinate = CLLocationCoordinate2D()
    @State var locations = [MKPointAnnotation]()
    var body: some View {
        ZStack{
            MapView(centerCoordinate: $centerCoordinate, annotations: locations)
            Circle()
                .fill(Color.blue)
                .opacity(0.5)
                .frame(width: 32, height: 32, alignment: .center)
            VStack{
                Spacer()
                HStack{
                    Spacer()
                    Button(action: {
                        let newLocation = MKPointAnnotation()
                        newLocation.coordinate = centerCoordinate
                        locations.append(newLocation)
                    }){
                        Image(systemName: "plus")
                    }
                    .padding()
                    .background(Color.black.opacity(0.75))
                    .foregroundColor(.white)
                    .font(.title)
                    .clipShape(Circle())
                    .padding([.trailing, .bottom])
                }
            }
        }
        .edgesIgnoringSafeArea(.all)
    }
}
struct MapView: UIViewRepresentable{
    @Binding var centerCoordinate: CLLocationCoordinate2D
    var annotations: [MKPointAnnotation]
    
    func makeUIView(context: Context) -> MKMapView {
        let mapView = MKMapView()
        mapView.delegate = context.coordinator
        return mapView
    }
    // Callback function - when anything being sent to UIViewRepresentabel struct is changed
    func updateUIView(_ uiView: UIViewType, context: Context) {
        print("Updating UIView")
        if annotations.count != uiView.annotations.count{
            uiView.removeAnnotations(uiView.annotations)
            uiView.addAnnotations(annotations)
        }
    }
    
    func makeCoordinator() -> Coordinator {
        return Coordinator(self)
    }
    
    class Coordinator: NSObject, MKMapViewDelegate {
        let parent: MapView
        init(_ parent: MapView) {
            self.parent = parent
        }
        
        func mapViewDidChangeVisibleRegion(_ mapView: MKMapView) {
            parent.centerCoordinate = mapView.centerCoordinate
        }
    }
}

extension MKPointAnnotation{
    static var example: MKPointAnnotation{
        let point = MKPointAnnotation()
        point.coordinate = CLLocationCoordinate2D(latitude: 51.5, longitude: -0.13)
        point.title = "London"
        point.subtitle = "The home of 2012 Summer Olympics"
        return point
    }
}

【问题讨论】:

    标签: swift view binding


    【解决方案1】:

    不确定我是否理解你的问题,但让我试试。

    首先你的视图中有这个状态:

    @State var locations = [MKPointAnnotation]()
    

    接下来,您将其分配给:

    MapView(centerCoordinate: $centerCoordinate, annotations: locations)
    

    这意味着,每次您更改 locations 时,SwiftUI 都会使用新值重新渲染 MapView

    任何UIViewRepresentable 都必须实现函数updateUIView 以便在SwiftUI 重新渲染相应组件时接收这些更改。

    所以,每次你的MapView被渲染时,这个函数都会被触发:

    func updateUIView(_ uiView: UIViewType, context: Context) {
      print("Updating UIView")
      if annotations.count != uiView.annotations.count{
        uiView.removeAnnotations(uiView.annotations)
        uiView.addAnnotations(annotations)
      }
    }
    

    uiView.annotationsannotations 相互关联。目前uiView.annotations 发生变化,它只会在视图本身中产生副作用,并且不会更新给定的@State,因为它可能会创建无限渲染循环。

    【讨论】:

    • 感谢您的友好回复。但是,我遇到的问题是:当我更改 ContentView 中的位置变量(例如:向其中添加元素)时,MapView 中的注释变量是否也会更新?它们有什么联系吗?
    猜你喜欢
    • 2020-07-15
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-15
    • 2023-03-12
    • 2017-02-12
    相关资源
    最近更新 更多