Действие пользовательской кнопки выноски MapAnnotation не работаетIOS

Программируем под IOS
Ответить
Anonymous
 Действие пользовательской кнопки выноски MapAnnotation не работает

Сообщение Anonymous »

Я пытаюсь отобразить карту с настраиваемыми аннотациями (булавками) и настраиваемыми представлениями выносок в SwiftUI.
Моя цель:
  • Пользователь нажимает на отметку на карте.
  • Над отметкой появляется настраиваемое представление выноски.
  • Это представление выноски содержит кнопку «Показать детали».
  • Когда пользователь нажимает на нее При нажатии кнопки отображается лист с дополнительной информацией.
  • Если пользователь нажимает где-нибудь еще на карте (не на выноске), выноска должна быть закрыта.
Я реализовал собственный пин-код, и при нажатии на булавку выноска отображается правильно. Жест увольнения также работает, как и ожидалось. Однако кнопка внутри моего пользовательского представления выноски вообще не является интерактивной. Жест касания, по-видимому, используется картой, и действие кнопки никогда не срабатывает.
Мое текущее решение — представить лист сведений одновременно с выноской (т. е. при нажатии самой булавки), что не является желаемым для пользователя. Пользователь должен сначала увидеть выноску, а затем выбрать просмотр более подробной информации, нажав кнопку.
Как сделать кнопку внутри моего пользовательского CalloutView (которая представлена ​​в виде .overlay MapAnnotation) интерактивной, чтобы она могла инициировать представление листа?
Я бы предпочел решение, использующее только SwiftUI. Однако, если это известное ограничение, которое невозможно преодолеть, я открыт для решения, основанного на UIKit (MKMapView), но я был бы признателен за объяснение того, почему чистый подход SwiftUI невозможен.
import SwiftUI
import MapKit

struct Location: Identifiable, Equatable {
let id = UUID()
let name: String
let coordinate: CLLocationCoordinate2D

static func == (lhs: Location, rhs: Location) -> Bool {
lhs.id == rhs.id
}
}

// Presented as a sheet
struct LocationDetailView: View {
let location: Location

var body: some View {
VStack(spacing: 16) {
Text(location.name)
.font(.largeTitle)
Text("Details about \(location.name) would be displayed here.")
.font(.body)
.foregroundColor(.secondary)
}
.padding()
.navigationTitle("Location Details")
.navigationBarTitleDisplayMode(.inline)
}
}

// Custom Callout View
struct CustomCalloutView: View {
let location: Location
var onDetailsTapped: () -> Void

var body: some View {
VStack(alignment: .leading, spacing: 8) {
Text(location.name)
.font(.headline)

// Button action is never called.
Button(action: {
print("Info button tapped for \(location.name)")
onDetailsTapped()
}) {
HStack {
Text("Show Details")
Image(systemName: "info.circle")
}
.padding(.vertical, 8)
.padding(.horizontal, 12)
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(8)
}
.buttonStyle(.plain)
}
.padding(12)
.background(Color(uiColor: .systemBackground))
.cornerRadius(10)
.shadow(radius: 5)
.frame(width: 200)

}
}

struct MapContentView: View {

@State private var region = MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: 34.0522, longitude: -118.2437), // Los Angeles
span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2)
)

private let locations: [Location] = [
.init(name: "City Hall", coordinate: .init(latitude: 34.0522, longitude: -118.2437)),
.init(name: "Dodger Stadium", coordinate: .init(latitude: 34.0739, longitude: -118.2400)),
.init(name: "Santa Monica Pier", coordinate: .init(latitude: 34.0100, longitude: -118.4969))
]

@State private var selectedLocation: Location?

@State private var locationForSheet: Location?

var body: some View {
NavigationView {
Map(coordinateRegion: $region, annotationItems: locations) { location in
MapAnnotation(coordinate: location.coordinate) {
Image(systemName: "mappin.and.ellipse")
.font(.title)
.foregroundColor(.red)
.background(Circle().fill(Color.white))
.shadow(radius: 1)
.overlay(
Group {
if selectedLocation == location {
CustomCalloutView(location: location) {
self.locationForSheet = location
}
.offset(y: -55)
}
}
)
.onTapGesture {
print("Pin Tapped: \(location.name)")
withAnimation(.spring()) {
selectedLocation = location
}

// Current Workaround:
// Because the callout button doesn't work, the sheet
// is triggered at the same time as the callout.
// This is the behavior I want to avoid.
self.locationForSheet = location
}
}
}
.navigationTitle("Map Example")
.navigationBarTitleDisplayMode(.inline)
.ignoresSafeArea(edges: .bottom)
.sheet(item: $locationForSheet) { location in
NavigationView {
LocationDetailView(location: location)
}
}
.simultaneousGesture(
// Tap gesture on the map to dismiss the callout
TapGesture().onEnded { _ in
print("Map Tapped: Dismissing callout")
withAnimation(.spring()) {
selectedLocation = nil
}
}
)
}
}
}

#Preview {
MapContentView()
}


Подробнее здесь: https://stackoverflow.com/questions/798 ... ot-working
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»