GithubHelp home page GithubHelp logo

pauljohanneskraft / map Goto Github PK

View Code? Open in Web Editor NEW
176.0 8.0 45.0 85 KB

MKMapView wrapper for SwiftUI as drop-in to MapKit's SwiftUI view. Easily extensible annotations and overlays, iOS 13 support and backwards compatible with MKAnnotation and MKOverlay!

License: MIT License

Swift 99.02% Ruby 0.98%
ios macos mapkit swiftui tvos watchos core-location corelocation map mkannotation

map's Introduction

Map

MapKit's SwiftUI implementation of Map (UIKit: MKMapView) is very limited. This library can be used as a drop-in solution (i.e. it features a very similar, but more powerful and customizable interface) to the existing Map and gives you so much more features and control:

πŸš€ Features

πŸ“ Annotations

  • Create annotations from annotationItems as in the default MapKit SwiftUI implementation.
  • Or: Create annotations from a list of MKAnnotation objects - you can even use your existing MKAnnotationView implementations!

πŸ–Ό Overlays

  • Use a SwiftUI-style API based on Identifiable with overlay items and a closure to create overlays from these items
  • Or: Use existing MKOverlay / MKOverlayRenderer objects

πŸ›  Appearance / Behavior Customization

πŸ‘€ Adapt visibility of:

  • Buildings
  • Compass
  • Pitch control
  • Scale
  • Traffic
  • User heading
  • User location
  • Zoom controls

πŸͺ„ Custom controls

πŸ’» Supported Platforms

πŸ“± iOS 13+
πŸ–₯ macOS 10.15+
πŸ“Ί tvOS 13+
⌚️ watchOS 6+

Keep in mind that not all features are equally available on all platforms (based on what MapKit provides) and therefore might not be available here either. However, if you can use them using UIKit, there is a very high change that it is available here as well - if not: Let me/us know by creating an issue!

πŸ§‘πŸ½β€πŸ’» Usage on iOS, macOS and tvOS

Very similar to MapKit's SwiftUI wrapper, you simply create a Map view inside the body of your view. You can define a region or mapRect, the map type (MKMapType), a pointOfInterestFilter (MKPointOfInterestFilter), interactions Modes (with values: .none, .pitch, .pan, .zoon, .rotate and .all - which can be combined as you wish) and showsUserLocation.

import Map
import SwiftUI

struct MyMapView: View {

    let locations: [MyLocation]
    let directions: MKDirections.Response
    
    @State private var region = MKCoordinateRegion()
    @State private var userTrackingMode = UserTrackingMode.follow

    var body: some View {
        Map(
          coordinateRegion: $region,
          type: .satelliteFlyover,
          pointOfInterestFilter: .excludingAll,
          informationVisibility: .default.union(.userLocation),
          interactionModes: [.pan, .rotate],
          userTrackingMode: $userTrackingMode,
          annotationItems: locations,
          annotationContent: { location in
              ViewMapAnnotation(coordinate: location.coordinate) {
                  Color.red
                    .frame(width: 24, height: 24)
                    .clipShape(Circle())
              }
          },
          overlays: directions.routes.map { $0.polyline },
          overlayContent: { overlay in
              RendererMapOverlay(overlay: overlay) { _, overlay in
                  if let polyline = overlay as? MKPolyline else {
                      let isFirstRoute = overlay === directions.routes.first?.overlay
                      let renderer = MKPolylineRenderer(polyline: polyline)
                      renderer.lineWidth = 6
                      renderer.strokeColor = isFirstRoute ? .systemBlue : .systemGray
                      return renderer
                  } else {
                      assertionFailure("Unknown overlay type found.")
                      return MKOverlayRenderer(overlay: overlay)
                  }
              }
          }
        )
        .onAppear {
            region = // ...
        }
    }

}

πŸ“ Annotations: The modern approach

You can use a collection of items conforming to Identifiable and a closure that maps an item to its visual representation (available types: MapPin, MapMarker and ViewMapAnnotation for custom annotations from any SwiftUI View).

Map(
    coordinateRegion: $region,
    annotationItems: items,
    annotationContent: { item in
        if <first condition> {
            ViewMapAnnotation(coordinate: location.coordinate) {
                Color.red
                    .frame(width: 24, height: 24)
                    .clipShape(Circle())
             }
         else if <second condition> {
             MapMarker(coordinate: item.coordinate, tint: .red) // tint is `UIColor`, `NSColor` or `Color`
         } else {
             MapPin(coordinate: item.coordinate, tint: .blue) // tint is `UIColor`, `NSColor` or `Color`
         }
     }
)

πŸ“Œ Annotations: The old-fashioned approach

Moving an existing code base over to SwiftUI is hard, especially when you want to keep methods, types and properties that you have previously built. This library, therefore, allows the use of MKAnnotation instead of being forced to the new Identifiable style. In the additional closure, you can use one of the options mentioned in the modern-approach. Alternatively, we also have an option to use your own MKAnnotationView implementations. Simply create a struct conforming to the following protocol and you are good to go.

public protocol MapAnnotation {

    static func registerView(on mapView: MKMapView)
    
    var annotation: MKAnnotation { get }

    func view(for mapView: MKMapView) -> MKAnnotationView?
    
}

In registerView(on:), your custom annotation implementation can register a cell type for dequeuing using MKMapView.register(_:forAnnotationViewWithReuseIdentifier:). To dequeue the registered cell, implement the view(for:) method, similar to MKMapViewDelegate.mapView(_:viewFor:).

Note: Please make sure not to create the value of the property annotation dynamically. You can either use an existing object or create the object in your type's initializer. Simply put: Do not make annotation a computed property!

πŸŒƒ Overlays: The modern approach

Similarly to how annotations are handled, you can also use a collection of Identifiable and a closure mapping it to specific overlay types. These overlay types currently contain MapCircle, MapMultiPolygon, MapMultiPolyline, MapPolygon and MapPolyline and this list can easily be extended by creating a type conforming to the following protocol:

public protocol MapOverlay {

    var overlay: MKOverlay { get }
    
    func renderer(for mapView: MKMapView) -> MKOverlayRenderer
    
}

In your implementation, the renderer(for:) method creates a renderer for the overlay, similar to MKMapViewDelegate.mapView(_:rendererFor:).

Note: Please make sure not to create the value of the property overlay dynamically. You can either use an existing object or create the object in your type's initializer. Simply put: Do not make overlay a computed property!

πŸ–Ό Overlays: The old-fashioned approach

Especially when working with MKDirections or when more customization to the MKOverlayRenderer is necessary, you can also provide an array of MKOverlay objects and use your own MKOverlayRenderer.

For this, we provide RendererMapOverlay:

Map(
    coordinateRegion: $region,
    overlays: directions.routes.map { $0.polyline },
    overlayContent: { overlay in
        RendererMapOverlay(overlay: overlay) { mapView, overlay in
            guard let polyline = overlay as? MKPolyline else {
                assertionFailure("Unknown overlay type encountered.")
                return MKMapOverlayRenderer(overlay: overlay)
            }
            let renderer = MKPolylineRenderer(polyline: polyline)
            renderer.lineWidth = 4
            renderer.strokeColor = .red
            return renderer
        }
    }
)

πŸͺ„ Custom Map Controls

For the use of MapCompass, MapPitchControl, MapScale and MapZoomControl you will need to associate both the Map and the control with some form of a shared key. This key needs to conform to the Hashable protocol. For each key, there must only be one Map (or MKMapView respectively) in the view hierarchy at once.

Example: We want to display a scale overlay at the topLeading edge of a Map. To accomplish this, let's take a look at the following code snippet.

struct MyMapView: View {

    @Binding var region: MKCoordinateRegion
    
    var body: some View {
        Map(coordinateRegion: $region)
            .mapKey(1)
            .overlay(alignment: .topLeading) {
                MapScale(key: 1, alignment: .leading, visibility: .visible)
                    .fixedSize()
                    .padding(12)
            }
    }
}

⌚️ Usage on watchOS

Since MapKit is very limited on watchOS, there is a separate (also similary limited) wrapper in this library. If you are only targeting watchOS, it might not make sense to use this library as the underlying feature set is already very limited (e.g. no overlay support, only a few kinds of possible annotations, etc).

We do include a drop-in interface though for projects that target multiple platforms and share code extensively across these platforms.

Map(
    coordinateRegion: $region,
    informationVisibility: [.userHeading, .userLocation],
    userTrackingMode: $userTrackingMode,
    annotationItems: annotationItems,
    annotationContent: { item in
        if <first condition> {
            ImageAnnotation(coordinate: item.coordinate, image: UIImage(...), centerOffset: CGPoint(x: 0, y: -2) 
        } else {
            MapPin(coordinate: item.coordinate, color: .red) // color can only be red, green or purple
        }
    }
)

πŸ”© Installation

Map is currently only available via Swift Package Manager. See this tutorial by Apple on how to add a package dependency to your Xcode project.

✍️ Author

Paul Kraft

πŸ“„ License

Map is available under the MIT license. See the LICENSE file for more info.

map's People

Contributors

nasircsms avatar pauljohanneskraft avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

map's Issues

Issue with userTrackingMode

I tried following the directions in your readme and here online, however I am getting an error when trying to set the userTrackingMode -> Cannot find 'UserTrackingMode' in scope

@State private var userTrackingMode = UserTrackingMode.follow

If I try setting to this

@State private var userTrackingMode = MapUserTrackingMode.follow

I get the following error -> Ambiguous use of 'follow'

Any help would be appreciated.

ViewMapAnnotation not updating location

Using MapAnnotation I can change the coordinate of an item and it changes on the map. However if I use ViewMapAnnotation, it doesn't change the location.

Here is a code example. Using MapAnnotation you can see the point move around. If you change it to ViewMapAnnotation, the point doesn't move at all.

import SwiftUI
import MapKit
import Map

struct ContentView: View {
    
    @State private var map = MKCoordinateRegion(
        center: CLLocationCoordinate2D(latitude: 40.4, longitude: -3.7),
        span: MKCoordinateSpan(latitudeDelta: 2, longitudeDelta: 2)
    )
    
    @State var locations = [
        MyLocation(coordinate:CLLocationCoordinate2D(latitude:40.4, longitude: -3.7))]
    
    var body: some View {
        Map(
            coordinateRegion: $map,
            annotationItems: locations,
            annotationContent: { location in
                MapAnnotation(coordinate: location.coordinate) { // Change MapAnnotation to ViewMapAnnotation here
                    Circle()
                    .frame(width: 25, height: 25)
                    .foregroundColor(.red)
                }
            }
        )
        .task({
            while(true)
            {
                try? await Task.sleep(nanoseconds: 1_000_000_000)
                locations[0].coordinate = CLLocationCoordinate2D(
                    latitude: 40.4 + Double.random(in: -0.5...0.5),
                    longitude: -3.7 + Double.random(in: -0.5...0.5))
            }
        })
    }
        
}

struct MyLocation : Identifiable {
    let id = UUID()
    var coordinate: CLLocationCoordinate2D
}

MapUserTrackingMode.follow is Ambiguous

Hi there and thanks for the good work!

when writing the following:
@State private var userTrackingMode = MapUserTrackingMode.follow

I get the following error: Ambiguous use of 'follow'

Hope not to bother you with typical newbie stupid stuff, but cannot find a way to go around this...

I'm very interested in this project!

I'm having trouble getting a demo app to compile and run. Would you be willing to create a very simple example app to get a new users for your package up and running?

onTapGesture not working

The onTapGesture is not working inside the ViewMapAnnotation, here is my code:

 `Map(
        coordinateRegion: $region,
        type: .standard,
        pointOfInterestFilter: .includingAll,
        interactionModes: [.all],
        annotationItems: evChargerManager.evChargers,
        annotationContent: { charger in

            ViewMapAnnotation(coordinate: (charger.addressInfo?.coordinates)!) {

                Image(K.Images.SupplementarilyIcons.pinpoint)
                    .resizable()
                    .frame(width: 40, height: 40, alignment: .center)
                    .onTapGesture {
                        showingSheet.toggle()
                    }
                    .sheet(isPresented: $showingSheet) {
                        EVChargerView(evCharger: charger)
                    } //: SHEET

            } //: VIEW MAP ANNOTATION

        } //: ANNOTATION CONTENT

    ) //: MAP`

Package not recognised

Dear Paul,

I added your package 'Map' to my project as explained by Apple.
My project has a working map based on MapKit but I want to use extended facilities based on your package.
It is visible as a Package dependency as well as listed under'Frameworks, Libraries and embedded Content'.

However it seems not to be recognised by Xcode as I get 'Cannot find type 'MKCoordinateRegion' in scope and similar errors for MyLocation, MKDirections and UserTrackingMode.

Any ideas how to resolve this.
Kind regards, ahartman, belgium

watchOS support for overlays?

Hi,

trying to render some images on top of a map on my Apple Watch (rain radar gifs on top of map)

I did this on the web previously and thought, gee, that'd be nice on my wrist!

Having some difficulty trying to render images on the map, I found your library.
After adding it... Found this #if !os(watchOS) ... code ... #endif

Bummer.

So, simple question, is it a case of impossible at the moment or ... something else? It seems deliberate!

thanks for your time,
keyle

How to display a small window after clicking on annotation?

Looks like a great project, thanks for your work! Is it possible to click on a view in ViewMapAnnotation to bring up a small window with more information? I tried putting a Button in it, or just a TapGesture and clicking on it would display a different view, but it didn't work.

iOS 15 - SwiftUI - Xcode 13.4 - Swift Package Manager

Annotations aren't immobile and move with zoom

When I use ignoreSafeArea or edgesIgnoringSafeArea(.all) in my code and if I zoom, my annotations aren't immobile and move.
To fix the problem I have to add a title with a VStack above my map
Some one have an idea of the problem ?

Thank you
Good work with the package, it's really impressive

Carte(coordinateRegion: $region ,type: MKStandardMapConfiguration() , userTrackingMode: $userTrackingMode ,annotationItems: MockedDataMapAnnotation,
annotationContent: { location in
CarteAnnotation(coordinate: CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude)) {
VStack(spacing: 0) {
Image(systemName: "map")
.resizable()
.scaledToFit()
.frame(width: 15, height: 15)
.font(.headline)
.foregroundColor(Color.black)
.padding(6)
.background(Color.white)
.clipShape(Circle())
Image(systemName: "triangle.fill")
.resizable()
.scaledToFit()
.foregroundColor(.black)
.frame(width: 10, height: 10)
.rotationEffect(Angle(degrees: 180))
.offset(y: -1.5)
.padding(.bottom, 40)
}
}
},
overlays: [
MKPolyline(coordinates: polylineCoordinates, count: polylineCoordinates.count)
],overlayContent: { overlay in
RendererCarteOverlay(overlay: overlay) { _, overlay in

                if let polyline = overlay as? MKPolyline {
                    let renderer = MKPolylineRenderer(polyline: polyline)
                    renderer.lineWidth = 2
                    renderer.lineCap = .butt
                    renderer.lineJoin = .miter
                    renderer.miterLimit = 0
                    renderer.lineDashPhase = 0
                    renderer.lineDashPattern = [10,5]
                    renderer.strokeColor = .orange
                    return renderer
                } else {
                     assertionFailure("Unknown overlay type found.")
                     print("Probleme overlay")
                     return MKOverlayRenderer(overlay: overlay)
                }
            }
        }
   ).edgesIgnoringSafeArea(.all)

impossible to have my liste of annotations

Hello !

Thanks for the great work in this project !
I just Have a small issues when using map annotations.

I've got a structured array :

var places: [PointOfInterest] = []

struct PointOfInterest: Identifiable {

    let id = UUID()
    let name: String
    let latitude: Double
    let longitude: Double
    
    var coordinate: CLLocationCoordinate2D {
        CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
    }
}

And I use it like this in my Map :

Map(coordinateRegion: $region, type: getTypeFromUD(), annotationItems: places, annotationContent: { item in

                MapMarker(coordinate: item.coordinate, tint: UIColor(.red))   
  
})

My array receive data during the user use the app. When I go to my view where is my map I see only 1 pin which isn't at a corresponding place in my array. But can't see the other ?

I don't know how to deal with that ?

assertionFailure("Somehow a cluster contains an unknown annotation item.")

Hello!

I have a filter system in my App, which basically filters the visible annotations on the map. Based on some values, I show the appropriate annotations. I also cluster those annotations if needed. However, I noticed that if the annotation that I remove because of the new filter settings, is still in the clustering group, it throws the error assertionFailure("Somehow a cluster contains an unknown annotation item."). I guess I have to update all my clusters as I update my array of annotations. How do I do that? Thank you!

Yours faithfully,
Iraklis Eleftheriadis

User location not showed

Hi, I'm developing an application in SwifUI to estimate the power consumption of an e-bike based on the track chosen by the user; I'm implementing a Map initializing it as showed in the example file, but when I try to show also user position the map doesn't show the location.
I have implemented a CLLocationManager to manage user position and it works correctly, but in the example is not specified very well how to link the two components.

More appearance configurations

Possible additional appearance configurations:

  • showsBuildings
  • showsCompass
  • showsZoomControls
  • showsScale
  • showsTraffic
  • showsPitchControl

ViewMapAnnotation does not allow text

I'm trying to make an annotation with text and icon (like the official POI's in apple maps) but the text is not displayed.

This is the code I'm using, with SwiftUI maps it works but with this library it doesn't.

Map(
  coordinateRegion: $region,
  pointOfInterestFilter: .excludingAll,
  annotationItems: POIList){ item in
    ViewMapAnnotation(coordinate: item.coordinate) {
        VStack{
            Text("Text Here")
            Image(systemName: "leaf.circle.fill")
            
        }
        //MapPOIElementView(POI: item)
    }
  }

Expected result (MapKit):
Screenshot 2022-07-30 at 16 47 41

Actual result (Map):
Screenshot 2022-07-30 at 16 44 05

Using current zoom factor in Annotations

I'd like to display Annotations differently depending on the current zoom factor. Is there a way to access the current zoom factor? I couldn't find it... Thanks !

Fails to compile for macOS (Apple Silicon)

M1 iMac
macOS 13.2.1
Xcode 14.3

Haven't dove into the code, but compilation for macOS arm64 yields the following log excerpt:

SwiftCompile normal arm64 [PATH]/Map/Sources/Map/Map.swift (in target 'Map' from project 'Map')

...

[PATH]/Map/Sources/Map/Map.swift:55:139: error: contextual closure type '(MKClusterAnnotation, [AnnotationItems.Element]) -> (any MapAnnotation)?' expects 2 arguments, but 1 was used in closure body
        @OptionalMapAnnotationBuilder clusterAnnotation: @escaping (MKClusterAnnotation, [AnnotationItems.Element]) -> MapAnnotation? = { _ in nil },
                                                                                                                                          ^
                                                                                                                                           ,_ 
[PATH]/Map/Sources/Map/Map.swift:55:137: error: generic parameter 'AnnotationItems' could not be inferred
        @OptionalMapAnnotationBuilder clusterAnnotation: @escaping (MKClusterAnnotation, [AnnotationItems.Element]) -> MapAnnotation? = { _ in nil },
                                                                                                                                        ^
[PATH]/Map/Sources/Map/Map.swift:13:19: note: 'AnnotationItems' declared as parameter to type 'Map'
public struct Map<AnnotationItems: RandomAccessCollection, OverlayItems: RandomAccessCollection>
                  ^
[PATH]/Map/Sources/Map/Map.swift:285:32: error: extra argument 'clusterAnnotation' in call
            clusterAnnotation: { annotation, _ in clusterAnnotation(annotation) },
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[PATH]/Map/Sources/Map/Map.swift:493:32: error: cannot convert value of type '([AnnotationItems.Element]) -> (any MapAnnotation)?' to expected argument type '(MKClusterAnnotation, [AnnotationItems.Element]) -> (any MapAnnotation)?'
            clusterAnnotation: clusterAnnotation,
                               ^
[PATH]/Map/Sources/Map/Map.swift:493:32: error: cannot convert value of type '([AnnotationItems.Element]) -> (any MapAnnotation)?' to expected argument type '(MKClusterAnnotation, [AnnotationItems.Element]) -> (any MapAnnotation)?'
            clusterAnnotation: clusterAnnotation,
                               ^
[PATH]/Map/Sources/Map/Map.swift:524:32: error: cannot convert value of type '([AnnotationItems.Element]) -> (any MapAnnotation)?' to expected argument type '(MKClusterAnnotation, [AnnotationItems.Element]) -> (any MapAnnotation)?'
            clusterAnnotation: clusterAnnotation,
                               ^
[PATH]/Map/Sources/Map/Map.swift:524:32: error: cannot convert value of type '([AnnotationItems.Element]) -> (any MapAnnotation)?' to expected argument type '(MKClusterAnnotation, [AnnotationItems.Element]) -> (any MapAnnotation)?'
            clusterAnnotation: clusterAnnotation,
                               ^
[PATH]/Map/Sources/Map/Map.swift:558:32: error: cannot convert value of type '([AnnotationItems.Element]) -> (any MapAnnotation)?' to expected argument type '(MKClusterAnnotation, [AnnotationItems.Element]) -> (any MapAnnotation)?'
            clusterAnnotation: clusterAnnotation,
                               ^
[PATH]/Map/Sources/Map/Map.swift:558:32: error: cannot convert value of type '([AnnotationItems.Element]) -> (any MapAnnotation)?' to expected argument type '(MKClusterAnnotation, [AnnotationItems.Element]) -> (any MapAnnotation)?'
            clusterAnnotation: clusterAnnotation,
                               ^
[PATH]/Map/Sources/Map/Map.swift:592:32: error: cannot convert value of type '([AnnotationItems.Element]) -> (any MapAnnotation)?' to expected argument type '(MKClusterAnnotation, [AnnotationItems.Element]) -> (any MapAnnotation)?'
            clusterAnnotation: clusterAnnotation,
                               ^
[PATH]/Map/Sources/Map/Map.swift:592:32: error: cannot convert value of type '([AnnotationItems.Element]) -> (any MapAnnotation)?' to expected argument type '(MKClusterAnnotation, [AnnotationItems.Element]) -> (any MapAnnotation)?'
            clusterAnnotation: clusterAnnotation,
                               ^
[PATH]/Map/Sources/Map/Map.swift:711:32: error: contextual closure type '(MKClusterAnnotation, [IdentifiableObject<any MKAnnotation>]) -> (any MapAnnotation)?' expects 2 arguments, but 1 was used in closure body
            clusterAnnotation: { clusterAnnotation($0.map(\.object)) },
                               ^
[PATH]/Map/Sources/Map/Map.swift:711:55: error: value of type 'MKClusterAnnotation' has no member 'map'
            clusterAnnotation: { clusterAnnotation($0.map(\.object)) },
                                                   ~~ ^~~
[PATH]/Map/Sources/Map/Map.swift:711:59: error: cannot infer key path type from context; consider explicitly specifying a root type
            clusterAnnotation: { clusterAnnotation($0.map(\.object)) },
                                                          ^
                                                           <#Root#>
[PATH]/Map/Sources/Map/Map.swift:745:32: error: contextual closure type '(MKClusterAnnotation, [IdentifiableObject<any MKAnnotation>]) -> (any MapAnnotation)?' expects 2 arguments, but 1 was used in closure body
            clusterAnnotation: { clusterAnnotation($0.map(\.object)) },
                               ^
[PATH]/Map/Sources/Map/Map.swift:745:55: error: value of type 'MKClusterAnnotation' has no member 'map'
            clusterAnnotation: { clusterAnnotation($0.map(\.object)) },
                                                   ~~ ^~~
[PATH]/Map/Sources/Map/Map.swift:745:59: error: cannot infer key path type from context; consider explicitly specifying a root type
            clusterAnnotation: { clusterAnnotation($0.map(\.object)) },
                                                          ^
                                                           <#Root#>
[PATH]/Map/Sources/Map/Map.swift:782:32: error: contextual closure type '(MKClusterAnnotation, [IdentifiableObject<any MKAnnotation>]) -> (any MapAnnotation)?' expects 2 arguments, but 1 was used in closure body
            clusterAnnotation: { clusterAnnotation($0.map(\.object)) },
                               ^
[PATH]/Map/Sources/Map/Map.swift:782:55: error: value of type 'MKClusterAnnotation' has no member 'map'
            clusterAnnotation: { clusterAnnotation($0.map(\.object)) },
                                                   ~~ ^~~
[PATH]/Map/Sources/Map/Map.swift:782:59: error: cannot infer key path type from context; consider explicitly specifying a root type
            clusterAnnotation: { clusterAnnotation($0.map(\.object)) },
                                                          ^
                                                           <#Root#>

[PATH]/Map/Sources/Map/Map.swift:55:139: Contextual closure type '(MKClusterAnnotation, [AnnotationItems.Element]) -> (any MapAnnotation)?' expects 2 arguments, but 1 was used in closure body

[PATH]/Map/Sources/Map/Map.swift:55:137: Generic parameter 'AnnotationItems' could not be inferred

[PATH]/Map/Sources/Map/Map.swift:285:32: Extra argument 'clusterAnnotation' in call

[PATH]/Map/Sources/Map/Map.swift:493:32: Cannot convert value of type '([AnnotationItems.Element]) -> (any MapAnnotation)?' to expected argument type '(MKClusterAnnotation, [AnnotationItems.Element]) -> (any MapAnnotation)?'

[PATH]/Map/Sources/Map/Map.swift:493:32: Cannot convert value of type '([AnnotationItems.Element]) -> (any MapAnnotation)?' to expected argument type '(MKClusterAnnotation, [AnnotationItems.Element]) -> (any MapAnnotation)?'

[PATH]/Map/Sources/Map/Map.swift:524:32: Cannot convert value of type '([AnnotationItems.Element]) -> (any MapAnnotation)?' to expected argument type '(MKClusterAnnotation, [AnnotationItems.Element]) -> (any MapAnnotation)?'

[PATH]/Map/Sources/Map/Map.swift:524:32: Cannot convert value of type '([AnnotationItems.Element]) -> (any MapAnnotation)?' to expected argument type '(MKClusterAnnotation, [AnnotationItems.Element]) -> (any MapAnnotation)?'

[PATH]/Map/Sources/Map/Map.swift:558:32: Cannot convert value of type '([AnnotationItems.Element]) -> (any MapAnnotation)?' to expected argument type '(MKClusterAnnotation, [AnnotationItems.Element]) -> (any MapAnnotation)?'

[PATH]/Map/Sources/Map/Map.swift:558:32: Cannot convert value of type '([AnnotationItems.Element]) -> (any MapAnnotation)?' to expected argument type '(MKClusterAnnotation, [AnnotationItems.Element]) -> (any MapAnnotation)?'

[PATH]/Map/Sources/Map/Map.swift:592:32: Cannot convert value of type '([AnnotationItems.Element]) -> (any MapAnnotation)?' to expected argument type '(MKClusterAnnotation, [AnnotationItems.Element]) -> (any MapAnnotation)?'

[PATH]/Map/Sources/Map/Map.swift:592:32: Cannot convert value of type '([AnnotationItems.Element]) -> (any MapAnnotation)?' to expected argument type '(MKClusterAnnotation, [AnnotationItems.Element]) -> (any MapAnnotation)?'

[PATH]/Map/Sources/Map/Map.swift:711:32: Contextual closure type '(MKClusterAnnotation, [IdentifiableObject<any MKAnnotation>]) -> (any MapAnnotation)?' expects 2 arguments, but 1 was used in closure body

[PATH]/Map/Sources/Map/Map.swift:711:55: Value of type 'MKClusterAnnotation' has no member 'map'

[PATH]/Map/Sources/Map/Map.swift:711:59: Cannot infer key path type from context; consider explicitly specifying a root type

[PATH]/Map/Sources/Map/Map.swift:745:32: Contextual closure type '(MKClusterAnnotation, [IdentifiableObject<any MKAnnotation>]) -> (any MapAnnotation)?' expects 2 arguments, but 1 was used in closure body

[PATH]/Map/Sources/Map/Map.swift:745:55: Value of type 'MKClusterAnnotation' has no member 'map'

[PATH]/Map/Sources/Map/Map.swift:745:59: Cannot infer key path type from context; consider explicitly specifying a root type

[PATH]/Map/Sources/Map/Map.swift:782:32: Contextual closure type '(MKClusterAnnotation, [IdentifiableObject<any MKAnnotation>]) -> (any MapAnnotation)?' expects 2 arguments, but 1 was used in closure body

[PATH]/Map/Sources/Map/Map.swift:782:55: Value of type 'MKClusterAnnotation' has no member 'map'

[PATH]/Map/Sources/Map/Map.swift:782:59: Cannot infer key path type from context; consider explicitly specifying a root type

How can we update the position of Annotations?

In my app a timer updates the positions every 15 seconds, but I don't want the old Annotation to be deleted and a new one created. The goal would be to update the annotation position with animation. Is this possible?

Support with documentation

This is not an issue perse but more like a feature request, the README.md has a few lines on how to draw polylines on map elements but doesn't seem to work or is not clear, is possible to add a basic example (even here, if it works ill create a pull request) of a basic implementation.

Thanks

Append a Text after an Image as ViewMapAnnotation not showed

I'm trying to use Map library to implement a Map where is showed some ViewMapAnnotation, as much as the user wants to show, but I'm not able to show a simple Text under the Image that represents the single annotation

This is my code for the map implementation:

Map(coordinateRegion: $searchService.region,
type: selectedMapStyle,
pointOfInterestFilter: .excludingAll,
informationVisibility: .default.union(.userLocation),
interactionModes: .all,
userTrackingMode: $userTracking,
annotationItems: selectedLandmark,
annotationContent: { location in
ViewMapAnnotation(coordinate: location.coordinate, title: location.name) {
VStack{
Image(systemName: "mappin.circle.fill")
.foregroundColor(.red)
.font(.title)
.padding()

                            Text("\(location.name)")
                                .font(.caption2)
                        }
                    }
                },
                    overlays:  renderRoutes.map {$0.polyline},
                    overlayContent: {overlay in
                    RendererMapOverlay(overlay: overlay) {_, overlay in
                        guard let polyline = overlay as? MKPolyline else {
                            assertionFailure("Unknown overlay type encountered!")
                            return MKOverlayRenderer(overlay: overlay)
                        }
                        let isAndataRoute = polyline === andataRoutes.first?.polyline
                        let renderer = MKPolylineRenderer(polyline: polyline)
                        renderer.lineWidth = 4
                        renderer.strokeColor = isAndataRoute ? .systemBlue : .systemCyan
                        updateRectRegion(rectangle: overlay.boundingMapRect)
                        return renderer
                    }
                }
                )
                .ignoresSafeArea()
                .background(
                    RoundedRectangle(cornerRadius: 30)
                )

I really hope that someone can help me because this is a project that I'm developing for the final exam at university πŸ˜„
P.S. Sorry, but I'm not able to use properly the code function of GitHub because every time that I paste the code, GitHub adds to it a lot of tab at the beginning of every line

ViewMapAnnotation doesn't support clustering

Screenshot 2022-11-27 at 1 26 15 PM

Unfortunately custom annotation views are required for my project. However, I've noticed that clustering gets turned off if I use ViewMapAnnotation

If I use MapMarker instead for example, it is clustered as anticipated
Screenshot 2022-11-27 at 1 27 30 PM

Running

We can't run this project using Xcode .
It was Building as well but it's didn't run on simulator?

MapAnnotations not centered properly

Not sure if the problem comes from your package or from MapKit directly. Whenever I add MapAnnotations, these are not centered on their middle point and rotate around another near point when rotating the map

Screen 2022-06-28 aΜ€ 23 40 05

The crazy thing is that this does not always happen. Rarely, after the app being compiled, it works perfectly...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.