Posts

Post marked as solved
10 Replies
The problem cropped up again, and I bit the bullet. In Xcode, I created a new project and copied all the source from the old to the new project. I recreated everything in the new project, meaning: set the bundle ID, version number, build number, launch screen et cetera. That fixed it. So, it's not the source files themselves, it's something in the project file(s). I did a manual diff between the <projectname>.xcodeproj/project.pbxproj of the old and the new project, but I gave up after staring 15 minutes at the incredibly messy diff. Preview now work.
Post marked as solved
10 Replies
After upgrading to Xcode 12.2 beta 3 (12B5035g), one failing preview offered an error: a unittest (i.e. an XCTestCase subclass) was not part of any target. Of course, it was part of the unittest target only. So I have no idea why the preview depended on that unittest file. I just deleted the file from Xcode, and for this project, the error "Failed to build ***.swift" keeps popping up above the preview but if I repeatedly hit Cmd-Shift-P, it does render. Edit: never mind, other views no longer render. Very frustrating.
Post marked as solved
10 Replies
Once, I found that the project had multiple targets. And the file wasn't a member of the currently selected target. But that only happened once. Other times, I found that repeatedly clicking the preview button (or repeatedly pressing Option-Cmd-P) fixed it. But most of the time, the preview is simply not appearing. Xcode 12.0 and 12.2 series are rough for me, right now.
Post marked as solved
2 Replies
There are multiple ways to go about this, but I like the approach of a State variable named "action" into your SwiftUI view, and via that variable, you update the map type. The following project has a number of examples of using UIKit stuff in your SwiftUI project. I already had a MapKit example, and have updated it to allow changing the map type: GitHub - https://github.com/bvankuik/UIViewRepresentableExamples The code in question: import SwiftUI import CoreLocation import MapKit extension CLLocationCoordinate2D { &#9;&#9;var description: String { &#9;&#9;&#9;&#9;String(format: "%.8f, %.8f", self.latitude, self.longitude) &#9;&#9;} } extension MapKitExample { &#9;&#9;struct PickerValues { &#9;&#9;&#9;&#9;let mapType: MKMapType &#9;&#9;&#9;&#9;let description: String &#9;&#9;} } struct MapKitExample: View { &#9;&#9;static let amsterdam = CLLocationCoordinate2D(latitude: 52.37403, &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;longitude: 4.88969) &#9;&#9;@State private var centerCoordinate = Self.amsterdam &#9;&#9;@State private var action: MapView.Action = .idle &#9;&#9;@State private var mapPickerSelection: Int = 0 &#9;&#9;let pickerValues: [PickerValues] = [// [.standard, .hybrid, .satellite] &#9;&#9;&#9;&#9;PickerValues(mapType: .standard, description: "Standard"), &#9;&#9;&#9;&#9;PickerValues(mapType: .hybrid, description: "Hybrid"), &#9;&#9;&#9;&#9;PickerValues(mapType: .satellite, description: "Satellite"), &#9;&#9;] &#9;&#9;var body: some View { &#9;&#9;&#9;&#9;let binding = Binding&lt;Int&gt;( &#9;&#9;&#9;&#9;&#9;&#9;get: { self.mapPickerSelection}, &#9;&#9;&#9;&#9;&#9;&#9;set: { newValue in &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;self.action = .changeType(mapType: self.pickerValues[newValue].mapType) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;self.mapPickerSelection = newValue &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;) &#9;&#9;&#9;&#9;return VStack { &#9;&#9;&#9;&#9;&#9;&#9;MapView(centerCoordinate: self.$centerCoordinate, action: self.$action) &#9;&#9;&#9;&#9;&#9;&#9;Picker(selection: binding, label: Text("Map type")) { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;ForEach(self.pickerValues.indices) { index in &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;Text(self.pickerValues[index].description).tag(index) &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;&#9;&#9;}.pickerStyle(SegmentedPickerStyle()) &#9;&#9;&#9;&#9;&#9;&#9;Text("Centered on: " + self.centerCoordinate.description) &#9;&#9;&#9;&#9;&#9;&#9;Button("Reset") { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;self.action = .reset(coordinate: Self.amsterdam) &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;.navigationBarTitle("MapKit Example") &#9;&#9;} } struct MapView: UIViewRepresentable { &#9;&#9;enum Action { &#9;&#9;&#9;&#9;case idle &#9;&#9;&#9;&#9;case reset(coordinate: CLLocationCoordinate2D) &#9;&#9;&#9;&#9;case changeType(mapType: MKMapType) &#9;&#9;} &#9;&#9;@Binding var centerCoordinate: CLLocationCoordinate2D &#9;&#9;@Binding var action: Action &#9;&#9;func makeUIView(context: Context) -> MKMapView { &#9;&#9;&#9;&#9;let mapView = MKMapView() &#9;&#9;&#9;&#9;mapView.delegate = context.coordinator &#9;&#9;&#9;&#9;mapView.centerCoordinate = self.centerCoordinate &#9;&#9;&#9;&#9;return mapView &#9;&#9;} &#9;&#9;func updateUIView(_ uiView: MKMapView, context: Context) { &#9;&#9;&#9;&#9;switch action { &#9;&#9;&#9;&#9;case .idle: &#9;&#9;&#9;&#9;&#9;&#9;break &#9;&#9;&#9;&#9;case .reset(let newCoordinate): &#9;&#9;&#9;&#9;&#9;&#9;uiView.delegate = nil &#9;&#9;&#9;&#9;&#9;&#9;uiView.centerCoordinate = newCoordinate &#9;&#9;&#9;&#9;&#9;&#9;DispatchQueue.main.async { &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;self.centerCoordinate = newCoordinate &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;self.action = .idle &#9;&#9;&#9;&#9;&#9;&#9;&#9;&#9;uiView.delegate = context.coordinator &#9;&#9;&#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;case .changeType(let mapType): &#9;&#9;&#9;&#9;&#9;&#9;uiView.mapType = mapType &#9;&#9;&#9;&#9;} &#9;&#9;} &#9;&#9;func makeCoordinator() -> Coordinator { &#9;&#9;&#9;&#9;Coordinator(self) &#9;&#9;} &#9;&#9;class Coordinator: NSObject, MKMapViewDelegate { &#9;&#9;&#9;&#9;var parent: MapView &#9;&#9;&#9;&#9;func mapViewDidChangeVisibleRegion(_ mapView: MKMapView) { &#9;&#9;&#9;&#9;&#9;&#9;parent.centerCoordinate = mapView.centerCoordinate &#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;init(_ parent: MapView) { &#9;&#9;&#9;&#9;&#9;&#9;self.parent = parent &#9;&#9;&#9;&#9;} &#9;&#9;} }