Как одновременно обнаружить нажатие на ссылку и координаты касания в SwiftUI?

В моем приложении SwiftUI некоторые части текста должны быть доступны для нажатия. При касании должны выполняться некоторые настраиваемые действия, не обязательно открывающие веб-страницу. В то же время мне нужно определить координаты крана. Я собирался использовать для этого обработчик жестов перетаскивания.

Я реализовал нажимаемый текст в виде ссылок, используя AttributedString. Проблема в том, что я не могу определить координаты нажатия, потому что обработчики жестов касания или перетаскивания не вызываются при нажатии на ссылку.

Любые идеи о том, как обнаружить нажатие на ссылку и одновременное нажатие на координаты в SwiftUI?

(Я бы не хотел использовать для этого веб-просмотр, потому что мое приложение — это приложение для чтения, которое имеет много функций, связанных с текстом.)

Ниже приведен пример кода. Я определил пользовательскую схему URL-адресов для своего приложения, чтобы иметь возможность реализовывать собственные обработчики для ссылок.

      import SwiftUI

struct TappableTextView: View {
    
    var body: some View {
        VStack {
            Text(makeAttributedString()).padding()
                .gesture(
                    DragGesture(minimumDistance: 0)
                        .onEnded({ (value) in
                            print("Text has been tapped at \(value.location)")
                        })
                )
            Spacer()
        }
        .onOpenURL { url in
            print("A link is tapped, url: \(url)")
        }
    }
    
    func makeAttributedString() -> AttributedString {
        var string = AttributedString("")
        
        let s1 = AttributedString("This is a long paragraph. Somewhere in the paragraph is ")

        var tappableText = AttributedString("tappable text")
        tappableText.link = URL(string: "customurlscheme:somedata")
        tappableText.foregroundColor = .green
        
        let s2 = AttributedString(". This is the rest of the paragraph. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.")
        
        string.append(s1)
        string.append(tappableText)
        string.append(s2)
        
        return string
    }
}

1 ответ

Вам нужно использоватьsimultaneousGesture(_:including:). Это связано с тем, что вы уже нажимаете на ссылку, поэтому обычный жест не происходит. С использованием simultaneousGestureозначает, что вы одновременно нажимаете на ссылку и можете получить координаты.

Код:

      Text(makeAttributedString()).padding()
    .simultaneousGesture(
        /* ... */
    )
Другие вопросы по тегам