Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ class MapItemController: NSObject, ObservableObject, Identifiable {
return false
}

return self.item == other.item
return self.hashValue == other.hashValue
}

override var hash: Int {
item.hashValue
}

@BackgroundPublished var item: MapItem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,13 @@ class MapItemSearchController: NSObject, ObservableObject {
guard
let currentRegion = coordinator?.region,
let otherItemsResultRegion,
let otherItemsRequestRegion
let otherItemsRequestRegion,
coordinator?.selectedMapItem == nil && coordinator?.selectedMapItemCluster == nil
else { return }

let regionChange = currentRegion.span.longitudeDelta / otherItemsRequestRegion.span.longitudeDelta
if
!MKMapRect(otherItemsResultRegion).contains(MKMapPoint(currentRegion.center)) ||
!MKMapRect(otherItemsRequestRegion).contains(MKMapPoint(currentRegion.center)) ||
!(0.65...1.5).contains(regionChange)
{
reload()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,13 @@ public class MapItemPickerController: NSObject, ObservableObject {
}

func manuallySet(selectedMapItem: MapItemController?) {
self.selectedMapItem = selectedMapItem
reloadSelectedAnnotation()
// This usually happens within a view update so we use a Task here
Task { @MainActor in
guard let mapView = currentMapView else { return }

self.selectedMapItem = selectedMapItem
reloadSelectedAnnotation()
}
}

func reloadSelectedAnnotation() {
Expand Down Expand Up @@ -86,7 +91,8 @@ extension MapItemPickerController: MKMapViewDelegate {
} else if let user = annotation as? MKUserLocation {
return mapView.dequeueReusableAnnotationView(withIdentifier: "userLocation") ??
MKUserLocationView(annotation: user, reuseIdentifier: "userLocation")
} else if let cluster = annotation as? MKClusterAnnotation, let coordinators = cluster.memberAnnotations as? [MapItemController] {
} else if let cluster = annotation as? MKClusterAnnotation, cluster.memberAnnotations.contains(where: { $0 is MapItemController }) {
let coordinators = cluster.memberAnnotations.filter({ $0 is MapItemController }) as! [MapItemController]
let occurancesByColor: [UIColor: Int]? = coordinators.reduce(into: [:]) { partialResult, coordinator in
partialResult[coordinator.item.uiColor, default: 0] += 1
}
Expand Down Expand Up @@ -127,23 +133,27 @@ extension MapItemPickerController: MKMapViewDelegate {
annotationSelectionHandler(annotation)
}

self.selectedMapItem = selectedMapItem
Task { @MainActor in
self.selectedMapItem = selectedMapItem
}
}

// This function is necessary since the annotation handed to `mapView(_ mapView: MKMapView, didDeselect annotation: MKAnnotation)` is sometimes nil. Casting this within the original function works in debug builds, but not in release builds (due to optimization, propably).
private func didDeselect(optional annotation: MKAnnotation?) {
guard let annotation = annotation else { return }

if let cluster = annotation as? MKClusterAnnotation, cluster == selectedMapItemCluster {
selectedMapItemCluster = nil
} else if
let eq1 = annotation as? MapAnnotationEquatable,
let eq2 = selectedMapItem as? MapAnnotationEquatable,
eq1.annotationIsEqual(to: eq2)
{
selectedMapItem = nil
} else if annotation === selectedMapItem {
selectedMapItem = nil
Task { @MainActor in
if let cluster = annotation as? MKClusterAnnotation, cluster == selectedMapItemCluster {
selectedMapItemCluster = nil
} else if
let eq1 = annotation as? MapAnnotationEquatable,
let eq2 = selectedMapItem as? MapAnnotationEquatable,
eq1.annotationIsEqual(to: eq2)
{
selectedMapItem = nil
} else if annotation === selectedMapItem {
selectedMapItem = nil
}
}
}

Expand Down Expand Up @@ -209,7 +219,7 @@ extension MapItemPickerController {
edgePadding: .init(
top: 16,
left: 16,
bottom: currentPresentationDetent == miniDetentIdentifier ? miniDetentHeight : standardDetentHeight,
bottom: (currentPresentationDetent == miniDetentIdentifier ? miniDetentHeight : standardDetentHeight) + 16,
right: TopRightButtons.Constants.size + TopRightButtons.Constants.padding * 2
),
animated: animated
Expand Down
17 changes: 16 additions & 1 deletion Sources/MapItemPicker/Data/MapItem/MapItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import SwiftUI
import AddressBook
import SchafKit

public struct MapItem: Equatable, Hashable, Codable {
public struct MapItem: Codable {
public init(name: String, location: CLLocationCoordinate2D, region: CLCodableCircularRegion? = nil, featureAnnotationType: FeatureType? = nil, category: MapItemCategory? = nil, notes: String? = nil, street: String? = nil, housenumber: String? = nil, postcode: String? = nil, cityRegion: String? = nil, city: String? = nil, state: String? = nil, stateRegion: String? = nil, country: String? = nil, phone: String? = nil, website: String? = nil, wikidataBrand: String? = nil, wikipediaBrand: String? = nil, hasVegetarianFood: ExclusivityBool? = nil, hasVeganFood: ExclusivityBool? = nil, indoorSeating: PlaceBool? = nil, outdoorSeating: PlaceBool? = nil, internetAccess: InternetAccessType? = nil, smoking: PlaceBool? = nil, takeaway: ExclusivityBool? = nil, wheelchair: WheelchairBool? = nil, level: String? = nil, openingHours: OpeningHours? = nil) {
self.name = name
self.location = location
Expand Down Expand Up @@ -255,3 +255,18 @@ class MapItemMKPlacemark: MKPlacemark {

// TODO: Country Code
}

extension MapItem: Hashable, Equatable {
public func hash(into hasher: inout Hasher) {
hasher.combine(name)
hasher.combine(category)
hasher.combine(city)
hasher.combine(stateRegion)
hasher.combine(state)
hasher.combine(country)
}

public static func ==(lhs: MapItem, rhs: MapItem) -> Bool {
lhs.hashValue == rhs.hashValue
}
}
Loading
Loading