feat: MarkerIconFactory can now return optional image. In this case MapManagers will show the default marker icon

This commit is contained in:
Ivan Smolin 2023-07-10 16:16:38 +03:00
parent 36019f7429
commit df2faa4cd5
9 changed files with 46 additions and 64 deletions

View File

@ -67,27 +67,18 @@ open class AppleMapManager<DataModel>: BaseMapManager<MKMapView,
}
public convenience init(map: MKMapView,
positionGetter: @escaping PositionGetter,
clusteringIdentifierGetter: @escaping (DataModel) -> ClusteringIdentifier,
iconFactory: DefaultMarkerIconFactory<DataModel>? = nil,
clusterIconFactory: DefaultClusterMarkerIconFactory<DataModel>? = nil,
mapViewDelegate: MKMapViewDelegate? = nil,
selectPlacemarkHandler: @escaping SelectPlacemarkHandler) {
self.init(map: map,
positionGetter: positionGetter,
clusteringIdentifierGetter: clusteringIdentifierGetter,
iconFactory: nil as DefaultMarkerIconFactory<DataModel>?,
clusterIconFactory: nil as DefaultClusterMarkerIconFactory<DataModel>?,
mapViewDelegate: mapViewDelegate,
selectPlacemarkHandler: selectPlacemarkHandler)
}
public convenience init(map: MKMapView,
mapViewDelegate: MKMapViewDelegate? = nil,
selectPlacemarkHandler: @escaping SelectPlacemarkHandler) where DataModel: MapLocatable & Clusterable, DataModel.ClusterIdentifier == ClusteringIdentifier, DataModel.Position == CLLocationCoordinate2D {
selectPlacemarkHandler: @escaping SelectPlacemarkHandler)
where DataModel: MapLocatable, DataModel.Position == CLLocationCoordinate2D,
DataModel: Clusterable, DataModel.ClusterIdentifier == ClusteringIdentifier {
self.init(map: map,
positionGetter: { $0.position },
clusteringIdentifierGetter: { $0.clusterIdentifier },
iconFactory: iconFactory,
clusterIconFactory: clusterIconFactory,
mapViewDelegate: mapViewDelegate,
selectPlacemarkHandler: selectPlacemarkHandler)
}

View File

@ -62,24 +62,16 @@ open class GoogleMapManager<DataModel>: BaseMapManager<GMSMapView,
}
public convenience init(map: GMSMapView,
positionGetter: @escaping PositionGetter,
iconFactory: DefaultMarkerIconFactory<DataModel>? = nil,
clusterIconFactory: DefaultClusterMarkerIconFactory<DataModel>? = nil,
mapViewDelegate: GMSMapViewDelegate? = nil,
selectPlacemarkHandler: @escaping SelectPlacemarkHandler) {
self.init(map: map,
positionGetter: positionGetter,
iconFactory: nil as DefaultMarkerIconFactory<DataModel>?,
clusterIconFactory: nil as DefaultClusterMarkerIconFactory<DataModel>?,
mapViewDelegate: mapViewDelegate,
selectPlacemarkHandler: selectPlacemarkHandler)
}
public convenience init(map: GMSMapView,
mapViewDelegate: GMSMapViewDelegate? = nil,
selectPlacemarkHandler: @escaping SelectPlacemarkHandler) where DataModel: MapLocatable, DataModel.Position == CLLocationCoordinate2D {
selectPlacemarkHandler: @escaping SelectPlacemarkHandler)
where DataModel: MapLocatable, DataModel.Position == CLLocationCoordinate2D {
self.init(map: map,
positionGetter: { $0.position },
iconFactory: iconFactory,
clusterIconFactory: clusterIconFactory,
mapViewDelegate: mapViewDelegate,
selectPlacemarkHandler: selectPlacemarkHandler)
}

View File

@ -23,7 +23,7 @@
import UIKit.UIImage
public final class AnyMarkerIconFactory<Model>: MarkerIconFactory {
public typealias IconProviderClosure = (Model, MarkerState) -> UIImage
public typealias IconProviderClosure = (Model, MarkerState) -> UIImage?
public var iconProviderClosure: IconProviderClosure
@ -35,7 +35,7 @@ public final class AnyMarkerIconFactory<Model>: MarkerIconFactory {
self.iconProviderClosure = { iconFactory.markerIcon(for: transform($0), state: $1) }
}
public func markerIcon(for model: Model, state: MarkerState) -> UIImage {
public func markerIcon(for model: Model, state: MarkerState) -> UIImage? {
iconProviderClosure(model, state)
}
}

View File

@ -37,12 +37,15 @@ open class DefaultCachableMarkerIconFactory<M, K: AnyObject>: DefaultMarkerIconF
super.init(createIconClosure: createIconClosure)
}
open override func markerIcon(for model: M, state: MarkerState) -> UIImage {
open override func markerIcon(for model: M, state: MarkerState) -> UIImage? {
let cacheKey = cacheKeyProvider(model, state)
guard let cachedIcon = cache.object(forKey: cacheKey) else {
let icon = super.markerIcon(for: model, state: state)
cache.setObject(icon, forKey: cacheKey)
if let icon {
cache.setObject(icon, forKey: cacheKey)
}
return icon
}

View File

@ -25,19 +25,26 @@ import Foundation.NSString
public final class DefaultClusterMarkerIconFactory<Model>: DefaultCachableMarkerIconFactory<[Model], NSString> {
public typealias RendererPreparationClosure = ([Model], DefaultClusterIconRenderer) -> Void
public var clusterIconRenderer: DefaultClusterIconRenderer
public var beforeRenderCallback: RendererPreparationClosure?
public init(beforeRenderCallback: RendererPreparationClosure? = nil) {
self.beforeRenderCallback = beforeRenderCallback
self.clusterIconRenderer = DefaultClusterIconRenderer()
super.init { [clusterIconRenderer] models, _ in
beforeRenderCallback?(models, clusterIconRenderer)
return clusterIconRenderer.renderCluster(of: models.count)
} cacheKeyProvider: { models, _ in
public static var defaultCacheKeyProvider: CacheKeyProvider {
{ models, _ in
String(models.count) as NSString
}
}
public var clusterIconRenderer: DefaultClusterIconRenderer
public var beforeRenderCallback: RendererPreparationClosure?
public init(clusterIconRenderer: DefaultClusterIconRenderer = DefaultClusterIconRenderer(),
beforeRenderCallback: RendererPreparationClosure? = nil,
cacheKeyProvider: @escaping CacheKeyProvider = defaultCacheKeyProvider) {
self.beforeRenderCallback = beforeRenderCallback
self.clusterIconRenderer = clusterIconRenderer
super.init(createIconClosure: { [clusterIconRenderer] models, _ in
beforeRenderCallback?(models, clusterIconRenderer)
return clusterIconRenderer.renderCluster(of: models.count)
}, cacheKeyProvider: cacheKeyProvider)
}
}

View File

@ -23,7 +23,7 @@
import UIKit.UIImage
open class DefaultMarkerIconFactory<M>: MarkerIconFactory {
public typealias CreateIconClosure = (M, MarkerState) -> UIImage
public typealias CreateIconClosure = (M, MarkerState) -> UIImage?
private let createIconClosure: CreateIconClosure
@ -31,11 +31,11 @@ open class DefaultMarkerIconFactory<M>: MarkerIconFactory {
self.createIconClosure = createIconClosure
}
open func markerIcon(for model: M, state: MarkerState) -> UIImage {
open func markerIcon(for model: M, state: MarkerState) -> UIImage? {
postprocess(icon: createIconClosure(model, state))
}
open func postprocess(icon: UIImage) -> UIImage {
open func postprocess(icon: UIImage?) -> UIImage? {
icon
}
}

View File

@ -25,5 +25,5 @@ import UIKit.UIImage
public protocol MarkerIconFactory {
associatedtype Model
func markerIcon(for model: Model, state: MarkerState) -> UIImage
func markerIcon(for model: Model, state: MarkerState) -> UIImage?
}

View File

@ -29,7 +29,7 @@ public final class StaticImageIconFactory<Model>: MarkerIconFactory {
self.image = image
}
public func markerIcon(for model: Model, state: MarkerState) -> UIImage {
public func markerIcon(for model: Model, state: MarkerState) -> UIImage? {
image
}
}

View File

@ -60,19 +60,8 @@ open class YandexMapManager<DataModel>: BaseMapManager<YMKMapView,
}
public convenience init(map: YMKMapView,
positionGetter: @escaping PositionGetter,
defaultMarkerIcon: UIImage,
selectPlacemarkHandler: @escaping SelectPlacemarkHandler) {
self.init(map: map,
positionGetter: positionGetter,
iconFactory: StaticImageIconFactory(image: defaultMarkerIcon),
clusterIconFactory: DefaultClusterMarkerIconFactory(),
selectPlacemarkHandler: selectPlacemarkHandler)
}
public convenience init(map: YMKMapView,
defaultMarkerIcon: UIImage,
iconFactory: DefaultMarkerIconFactory<DataModel>? = nil,
clusterIconFactory: DefaultClusterMarkerIconFactory<DataModel>? = nil,
selectPlacemarkHandler: @escaping SelectPlacemarkHandler)
where DataModel: MapLocatable, DataModel.Position == YMKPoint {