We are building a travel app and have a page with locations (about 1000) mapped using SwiftUI mostly with the latest iOS17 Mapkit code. However, our knowledge is only based in SwiftUI which currently has no native clustering abilities so we need to use UIKit to be able to add the standard iOS clustering. We have a very rough working version in UIKit but it involved changing a ton of the layout code over (which we wanted to avoid) but that may be due to us not knowing enough about how to integrate the two platforms.
Would the attached code be able to be integrated into UIKit to get the clustering working but without having to change all the SwiftUI layout, image, context menu, overlays code – eg keeping as much SwiftUI code as possible and just adding in to the UIKit code where necessary to get the map clustering working?
Appreciate any help you can offer – thanks.
Map(position: $position) {
UserAnnotation()
ForEach(filteredPlaces()) { place in
Annotation("(place.name)n(getSubcategoryName(for: place))", coordinate: CLLocationCoordinate2D(latitude: place.latitude, longitude: place.longitude), anchor: .bottom) {
VStack(spacing: 0) {
Spacer()
if let subCategoryId = place.subCategoryIds.first,
let subCategory = viewModel.subCategories.first(where: { $0.id == subCategoryId }),
let topCategory = viewModel.categories.first(where: { $0.subCategoryIds.contains(subCategoryId) }) {
Image(subCategory.imageUrl + "_icon")
.frame(width: 30, height: 30)
.aspectRatio(contentMode: .fit)
.padding(10)
.foregroundStyle(.white)
.background(
Circle()
.fill(getColorForTopCategory(topCategory.id))
.stroke(Color.white, lineWidth: 2)
)
.overlay(alignment: .topTrailing) {
place.isFavorite ? Image(systemName: "heart.circle.fill")
.symbolRenderingMode(.palette)
.foregroundStyle(place.isFavorite ? .red : .black, place.isFavorite ? .white : .white)
.font(.system(size: 24))
.shadow(radius: 5)
.offset(x: 10, y: -10) : nil
}
} else {
Image(systemName: "mappin.circle.fill")
.frame(width: 30, height: 30)
.aspectRatio(contentMode: .fit)
.padding(10)
.foregroundStyle(.white)
.background(Color.red)
.cornerRadius(30)
}
Image(systemName: "arrowtriangle.down.fill")
.foregroundStyle(getColorForTopCategory(viewModel.categories.first(where: { $0.subCategoryIds.contains(place.subCategoryIds.first ?? 0) })?.id ?? 0))
.frame(height: 5)
}
.onTapGesture {
selectedPlace = place
isSheetPresented = true
getlookAroundScene(for: place)
}
.contextMenu {
ForEach(place.subCategoryIds.compactMap { subCategoryId in
viewModel.subCategories.first(where: { $0.id == subCategoryId })
}, id: .id) { subCategory in
Button("Show Only: (subCategory.name)") {
selectedFilterCategory = subCategory.name
}
}
ForEach(topCategories(for: place), id: .id) { category in
Button("Show Only: (category.name)") {
selectedFilterCategory = category.name
}
}
}
}
}
}