From df2faa4cd5661007eec2842b8f4e7e8c2be710c7 Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Mon, 10 Jul 2023 16:16:38 +0300 Subject: [PATCH] feat: MarkerIconFactory can now return optional image. In this case MapManagers will show the default marker icon --- TIAppleMapUtils/Sources/AppleMapManager.swift | 23 +++++--------- .../Sources/GoogleMapManager.swift | 20 ++++-------- .../IconProviders/AnyMarkerIconFactory.swift | 4 +-- .../DefaultCachableMarkerIconFactory.swift | 7 +++-- .../DefaultClusterMarkerIconFactory.swift | 31 ++++++++++++------- .../DefaultMarkerIconFactory.swift | 6 ++-- .../IconProviders/MarkerIconFactory.swift | 2 +- .../StaticImageIconFactory.swift | 2 +- .../Sources/YandexMapManager.swift | 15 ++------- 9 files changed, 46 insertions(+), 64 deletions(-) diff --git a/TIAppleMapUtils/Sources/AppleMapManager.swift b/TIAppleMapUtils/Sources/AppleMapManager.swift index 2afd1c8b..28a53b66 100644 --- a/TIAppleMapUtils/Sources/AppleMapManager.swift +++ b/TIAppleMapUtils/Sources/AppleMapManager.swift @@ -67,27 +67,18 @@ open class AppleMapManager: BaseMapManager ClusteringIdentifier, + iconFactory: DefaultMarkerIconFactory? = nil, + clusterIconFactory: DefaultClusterMarkerIconFactory? = nil, mapViewDelegate: MKMapViewDelegate? = nil, - selectPlacemarkHandler: @escaping SelectPlacemarkHandler) { - - self.init(map: map, - positionGetter: positionGetter, - clusteringIdentifierGetter: clusteringIdentifierGetter, - iconFactory: nil as DefaultMarkerIconFactory?, - clusterIconFactory: nil as DefaultClusterMarkerIconFactory?, - 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) } diff --git a/TIGoogleMapUtils/Sources/GoogleMapManager.swift b/TIGoogleMapUtils/Sources/GoogleMapManager.swift index f3427fed..16068aa1 100644 --- a/TIGoogleMapUtils/Sources/GoogleMapManager.swift +++ b/TIGoogleMapUtils/Sources/GoogleMapManager.swift @@ -62,24 +62,16 @@ open class GoogleMapManager: BaseMapManager? = nil, + clusterIconFactory: DefaultClusterMarkerIconFactory? = nil, mapViewDelegate: GMSMapViewDelegate? = nil, - selectPlacemarkHandler: @escaping SelectPlacemarkHandler) { - - self.init(map: map, - positionGetter: positionGetter, - iconFactory: nil as DefaultMarkerIconFactory?, - clusterIconFactory: nil as DefaultClusterMarkerIconFactory?, - 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) } diff --git a/TIMapUtils/Sources/IconProviders/AnyMarkerIconFactory.swift b/TIMapUtils/Sources/IconProviders/AnyMarkerIconFactory.swift index ccebd849..df370558 100644 --- a/TIMapUtils/Sources/IconProviders/AnyMarkerIconFactory.swift +++ b/TIMapUtils/Sources/IconProviders/AnyMarkerIconFactory.swift @@ -23,7 +23,7 @@ import UIKit.UIImage public final class AnyMarkerIconFactory: 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: 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) } } diff --git a/TIMapUtils/Sources/IconProviders/DefaultCachableMarkerIconFactory.swift b/TIMapUtils/Sources/IconProviders/DefaultCachableMarkerIconFactory.swift index b29381d8..9d26d0d5 100644 --- a/TIMapUtils/Sources/IconProviders/DefaultCachableMarkerIconFactory.swift +++ b/TIMapUtils/Sources/IconProviders/DefaultCachableMarkerIconFactory.swift @@ -37,12 +37,15 @@ open class DefaultCachableMarkerIconFactory: 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 } diff --git a/TIMapUtils/Sources/IconProviders/DefaultClusterMarkerIconFactory.swift b/TIMapUtils/Sources/IconProviders/DefaultClusterMarkerIconFactory.swift index 04e800dc..8023eab6 100644 --- a/TIMapUtils/Sources/IconProviders/DefaultClusterMarkerIconFactory.swift +++ b/TIMapUtils/Sources/IconProviders/DefaultClusterMarkerIconFactory.swift @@ -25,19 +25,26 @@ import Foundation.NSString public final class DefaultClusterMarkerIconFactory: 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) + } } diff --git a/TIMapUtils/Sources/IconProviders/DefaultMarkerIconFactory.swift b/TIMapUtils/Sources/IconProviders/DefaultMarkerIconFactory.swift index 2fb403f5..e254add8 100644 --- a/TIMapUtils/Sources/IconProviders/DefaultMarkerIconFactory.swift +++ b/TIMapUtils/Sources/IconProviders/DefaultMarkerIconFactory.swift @@ -23,7 +23,7 @@ import UIKit.UIImage open class DefaultMarkerIconFactory: MarkerIconFactory { - public typealias CreateIconClosure = (M, MarkerState) -> UIImage + public typealias CreateIconClosure = (M, MarkerState) -> UIImage? private let createIconClosure: CreateIconClosure @@ -31,11 +31,11 @@ open class DefaultMarkerIconFactory: 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 } } diff --git a/TIMapUtils/Sources/IconProviders/MarkerIconFactory.swift b/TIMapUtils/Sources/IconProviders/MarkerIconFactory.swift index 919e338c..dd8b99c5 100644 --- a/TIMapUtils/Sources/IconProviders/MarkerIconFactory.swift +++ b/TIMapUtils/Sources/IconProviders/MarkerIconFactory.swift @@ -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? } diff --git a/TIMapUtils/Sources/IconProviders/StaticImageIconFactory.swift b/TIMapUtils/Sources/IconProviders/StaticImageIconFactory.swift index 65fad0aa..91f0de4a 100644 --- a/TIMapUtils/Sources/IconProviders/StaticImageIconFactory.swift +++ b/TIMapUtils/Sources/IconProviders/StaticImageIconFactory.swift @@ -29,7 +29,7 @@ public final class StaticImageIconFactory: MarkerIconFactory { self.image = image } - public func markerIcon(for model: Model, state: MarkerState) -> UIImage { + public func markerIcon(for model: Model, state: MarkerState) -> UIImage? { image } } diff --git a/TIYandexMapUtils/Sources/YandexMapManager.swift b/TIYandexMapUtils/Sources/YandexMapManager.swift index f9ae44e0..e45074e8 100644 --- a/TIYandexMapUtils/Sources/YandexMapManager.swift +++ b/TIYandexMapUtils/Sources/YandexMapManager.swift @@ -60,19 +60,8 @@ open class YandexMapManager: BaseMapManager? = nil, + clusterIconFactory: DefaultClusterMarkerIconFactory? = nil, selectPlacemarkHandler: @escaping SelectPlacemarkHandler) where DataModel: MapLocatable, DataModel.Position == YMKPoint {