translation
Extending existing types to support ObservableObject


More content welcome to follow the public account “Swift Garden”

Extend known types to support ObservableObject

Users can now place pins on the map, but they can’t do anything with them yet — they can’t attach titles and subtitles. Solving this problem took some thought because MKPointAnnotation’s title and subtitle used optional strings, and SwiftUI did not allow us to bind selectable text controls.

There are several ways to do this, but the simplest is to write an extension to MKPointAnnotation that wraps the calculation properties for title and subtitle, which means we need to make the class ObservableObject compliant. You can calculate the name of the property, for example, name, info, detail, and so on. But you’ll find it easier to remember by simply adding a wrapped prefix to the original name.

Swift: MKPointAnnotation-ObservableObject.swift swift: MKPointAnnotation- observableObject. swift swift: MKPointAnnotation-ObservableObject.swift swift: MKPointAnnotation-ObservableObject.swift swift

extension MKPointAnnotation: ObservableObject {
    public var wrappedTitle: String {
        get {
            self.title ?? "Unknown value"
        }

        set {
            title = newValue
        }
    }

    public var wrappedSubtitle: String {
        get {
            self.subtitle ?? "Unknown value"
        }

        set {
            subtitle = newValue
        }
    }
}Copy the code

Notice that I didn’t mark the property above as @published. The reason this works is that we don’t actually need to publish changes when these properties change, because we don’t need to keep refreshing the view as the user enters.

With this extension, we now have two non-selectable properties in mkPoint Notation that can be used to bind UI controls in the SwiftUI view. Now we can create a UI to edit the location tag.

Create a new SwiftUI view called “EditView” and introduce MapKit as follows:

struct EditView: View {@Environment(\.presentationMode) var presentationMode
    @ObservedObject var placemark: MKPointAnnotation

    var body: some View {
        NavigationView {
            Form {
                Section {
                    TextField("Name of Place", text: $placemark.wrappedTitle)
                    TextField("Description", text: $placemark.wrappedSubtitle)
                }
            }
            .navigationBarTitle("Edit location")
            .navigationBarItems(trailing: Button("Complete") {
                self.presentationMode.wrappedValue.dismiss()
            })
        }
    }
}Copy the code

Also modify the preview class code to compile:

struct EditView_Previews: PreviewProvider {
    static var previews: some View {
        EditView(placemark: MKPointAnnotation.example)
    }
}Copy the code

We need to display this view in two places. The first is in the ContentView: we want users to edit the location information immediately when they add a location, and the second is displayed when they click the Alert popup edit button.

Both cases are triggered by a Boolean condition, and we add an @state attribute to the ContentView:

@State private var showingEditScreen = falseCopy the code

Replace the previous // edit this place comment with the following code:

self.showingEditScreen = trueCopy the code

When you add a location, not only do you set this property to true, but you also set the selected location, the selectedPlace property, to add the following code under self.locations. Append (newLocation) :

self.selectedPlace = newLocation
self.showingEditScreen = trueCopy the code

Finally, we need to bind the showingEditScreen to a sheet so that our EditView can be displayed. Note that we can’t unpack selectedPlace with an if let, so we’ll do a simple non-null check and use it directly.

Add the following modifier to ContentView, after Alert:

.sheet(isPresented: $showingEditScreen) {
    if self.selectedPlace ! =nil {
        EditView(placemark: self.selectedPlace!) }}Copy the code

So much for editing pin titles and subtitles.


Related articles:

[SwiftUI 100 days] Bucket List – Part1

[SwiftUI 100 days] Bucket List – Part2

[SwiftUI 100 days] Bucket List – Part4


My official account here Swift and computer programming related articles, as well as excellent translation of foreign articles, welcome to pay attention to ~