最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

ios - The SwiftUI sheet view modifier in the code below doesn't launch on LongPress. Xcode 16.2 - Stack Overflow

programmeradmin1浏览0评论

In the code below, I want to allow the user to later edit the properties of a selected location in a new View as a sheet view modifier attached to the Map. It's not launching when I long press a previously selected location.

import SwiftUI
import MapKit

struct ContentView: View {
    @State private var userLocations = [UserLocation]()
    @State private var selectedPlace: UserLocation? = nil
    
    let startPosition = MapCameraPosition.region(
        MKCoordinateRegion(
            center: CLLocationCoordinate2D(latitude: 42.196, longitude: 24.747),
            span: MKCoordinateSpan(latitudeDelta: 10, longitudeDelta: 10)
        )
    )
    
    var body: some View {
        MapReader { proxy in
            Map(initialPosition: startPosition) {
                ForEach(userLocations) { location in
                    Annotation(location.name, coordinate: location.coordinate) {
                        Image(systemName: "star.circle")
                            .resizable()
                            .foregroundStyle(.red)
                            .frame(width: 44, height: 44)
                            .background(.white)
                            .clipShape(Circle())
                            .onLongPressGesture {
                                selectedPlace = location
                            }
                    }
                }
            }
            .onTapGesture { position in
                if let coordinate = proxy.convert(position, from: .local) {
                    let newLocation = UserLocation(
                        id: UUID(),
                        name: "New Location",
                        description: "",
                        latitude: coordinate.latitude,
                        longitude: coordinate.longitude
                    )
                    userLocations.append(newLocation)
                }
            }
            .sheet(item: $selectedPlace) { place in
                Text(place.name)
            }
        }
    }
}

Below is the location data struct in a separate Swift file

import Foundation
import MapKit 

struct UserLocation: Codable, Equatable, Identifiable {
    let id: UUID
    var name: String
    var description: String
    var latitude: Double
    var longitude: Double
    
    var coordinate: CLLocationCoordinate2D {
        CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
    }
}

I added prints in action places (onTapGesture, onLongPressGesture). The print in onTapGesture executes, and the locations do display on selection.

But no print on onLongPressGesture. Which means the LongPressGesture doesn't get triggered on Long Press. And that's beyond my understanding at the moment.

PS: SwiftUI beginner here. Thanks in advance for your help.

In the code below, I want to allow the user to later edit the properties of a selected location in a new View as a sheet view modifier attached to the Map. It's not launching when I long press a previously selected location.

import SwiftUI
import MapKit

struct ContentView: View {
    @State private var userLocations = [UserLocation]()
    @State private var selectedPlace: UserLocation? = nil
    
    let startPosition = MapCameraPosition.region(
        MKCoordinateRegion(
            center: CLLocationCoordinate2D(latitude: 42.196, longitude: 24.747),
            span: MKCoordinateSpan(latitudeDelta: 10, longitudeDelta: 10)
        )
    )
    
    var body: some View {
        MapReader { proxy in
            Map(initialPosition: startPosition) {
                ForEach(userLocations) { location in
                    Annotation(location.name, coordinate: location.coordinate) {
                        Image(systemName: "star.circle")
                            .resizable()
                            .foregroundStyle(.red)
                            .frame(width: 44, height: 44)
                            .background(.white)
                            .clipShape(Circle())
                            .onLongPressGesture {
                                selectedPlace = location
                            }
                    }
                }
            }
            .onTapGesture { position in
                if let coordinate = proxy.convert(position, from: .local) {
                    let newLocation = UserLocation(
                        id: UUID(),
                        name: "New Location",
                        description: "",
                        latitude: coordinate.latitude,
                        longitude: coordinate.longitude
                    )
                    userLocations.append(newLocation)
                }
            }
            .sheet(item: $selectedPlace) { place in
                Text(place.name)
            }
        }
    }
}

Below is the location data struct in a separate Swift file

import Foundation
import MapKit 

struct UserLocation: Codable, Equatable, Identifiable {
    let id: UUID
    var name: String
    var description: String
    var latitude: Double
    var longitude: Double
    
    var coordinate: CLLocationCoordinate2D {
        CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
    }
}

I added prints in action places (onTapGesture, onLongPressGesture). The print in onTapGesture executes, and the locations do display on selection.

But no print on onLongPressGesture. Which means the LongPressGesture doesn't get triggered on Long Press. And that's beyond my understanding at the moment.

PS: SwiftUI beginner here. Thanks in advance for your help.

Share Improve this question asked Jan 29 at 7:22 FamienFamien 231 silver badge4 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

The map is probably recognising your long press as a drag gesture to drag the map. It takes longer for a long press to be recognised compared to a drag gesture. The minimum duration for a long press is probably longer than the minimum duration required for a drag, which in turns is longer than the minimum duration required for a tap. If I set the minimum duration for a long press to be something small, like 0.1, .onLongPressGesture(minimumDuration: 0.1), then the long press is triggered.

You can fix this by making it detect long presses and drags simultaneously, as opposed to fetting about the long press as soon as the minimum duration for the drag is reached.

.simultaneousGesture(LongPressGesture().onEnded { _ in
    selectedPlace = location
})
发布评论

评论列表(0)

  1. 暂无评论