ios – How do I use Look Around View with Custom Annotations?


In this Swift project, I have a map with a custom annotation which is near the Apple infinite loop (so I can test it on a simulator). This annotation works.

When the marker for this location is tapped, a sheet that presents details about the location appears. This is where the Look Around View that was made available with iOS 17 should be but it is not working. I am unsure of how to get it to work, I assume all I need to do is pass through the coordinates but I must be missing something.

Here is the full code so you can test this (excluding the info.plist part):

struct Home: View {

    @Namespace private var locationSpace
    @State private var cameraPosition: MapCameraPosition = .region(.myRegion)
    @State private var mapSelection: MKMapItem?
    @State private var viewingRegion: MKCoordinateRegion?
    @State private var showDetails: Bool = false
    @State private var lookAroundScene: MKLookAroundScene?
    @State private var myAnnotations: [MKMapItem] = []
    let locationManager = CLLocationManager()
    
    var body: some View {
       
        NavigationStack {
            Map(position: $cameraPosition, selection: $mapSelection, scope: locationSpace) {

                ForEach(myAnnotations, id: \.self) { mapItem in
                    
                    let placemark = mapItem.placemark
                    
                    Marker(placemark.name ?? "", coordinate: placemark.coordinate)
                        .tint(.green)
                }
                
                UserAnnotation()
            }
            .onAppear {
                locationManager.requestWhenInUseAuthorization()
               
                MKMapView.appearance().userTrackingMode = .follow
                fetchMyAnnotations()
            }
            .mapStyle(.standard(pointsOfInterest: .excludingAll))
            .onMapCameraChange({ ctx in
                viewingRegion = ctx.region
            })
            .overlay(alignment: .topTrailing) {
                VStack(spacing: 15) {
                    MapCompass(scope: locationSpace)
                    
                    MapUserLocationButton(scope: locationSpace)
                }
                .buttonBorderShape(.circle)
                .padding()
            }
            .mapScope(locationSpace)
            .sheet(isPresented: $showDetails, onDismiss: {
                withAnimation(.snappy) {

                }
            }, content: {
                MapDetails()
                    .presentationDetents([.height(800)])
                    .presentationBackgroundInteraction(.enabled(upThrough: .height(800)))
                    .presentationCornerRadius(25)
                    .interactiveDismissDisabled(true)
            })
        }
        .onChange(of: mapSelection) { oldValue, newValue in
            
            showDetails = newValue != nil
           
            if let mapSelection = mapSelection {
                fetchLookAroundPreview()
            }
        }
    }
    
    @ViewBuilder
    func MapDetails() -> some View {
        VStack(spacing: 15) {
            HStack {
                Spacer()
                Button(action: {
                    
                    showDetails = false
                    withAnimation(.snappy) {
                        mapSelection = nil
                    }
                }, label: {
                    Image(systemName: "xmark.circle.fill")
                        .font(.title)
                        .foregroundStyle(.black)
                        .background(.white, in: .circle)
                })
            }
            ZStack {
                // Look around API
                if lookAroundScene == nil {
                    /// New Empty View API
                    ContentUnavailableView("No Preview Available", systemImage: "eye.slash")
                } else {
                    LookAroundPreview(scene: $lookAroundScene)
                }
            }
            .frame(height: 200)
            .clipShape(.rect(cornerRadius: 15))
            Spacer()
        }
        .padding(15)
    }
    
    func fetchMyAnnotations() {
        let coordinates = CLLocationCoordinate2D(latitude: 37.33489680799126, longitude: -122.03039070251354)
        let mapItem = MKMapItem(placemark: MKPlacemark(coordinate: coordinates))
        mapItem.name = "Annotation Name"

        myAnnotations.append(mapItem)
    }

    func fetchLookAroundPreview() {
        if let mapSelection {
            
            lookAroundScene = nil
            Task.detached(priority: .background) {
                let request = MKLookAroundSceneRequest(mapItem: mapSelection)
                lookAroundScene = try? await request.scene
            }
        }
    }
}

extension MKMapRect {
    func reducedRect(_ fraction: CGFloat = 0.35) -> MKMapRect {
        var regionRect = self

        let wPadding = regionRect.size.width * fraction
        let hPadding = regionRect.size.height * fraction
                    
        regionRect.size.width += wPadding
        regionRect.size.height += hPadding
                    
        regionRect.origin.x -= wPadding / 2
        regionRect.origin.y -= hPadding / 2
        
        return regionRect
    }
}

extension CLLocationCoordinate2D {
    static var myLocation: CLLocationCoordinate2D {
        return .init(latitude: 37.3346, longitude: -122.0090)
    }
}

extension MKCoordinateRegion {
    static var myRegion: MKCoordinateRegion {
        return .init(center: .myLocation, latitudinalMeters: 10000, longitudinalMeters: 10000)
    }
}

How do I use the Look Around View that is available in iOS 17?

Latest articles

spot_imgspot_img

Related articles

Leave a reply

Please enter your comment!
Please enter your name here

spot_imgspot_img