如何在 SwiftUI 中同时检测 link 上的点击和点击坐标?

How to detect a tap on a link and tap coordinates at the same time in SwiftUI?

在我的 SwiftUI 应用程序中,文本的某些部分需要可点击。点击时,应该会发生一些自定义操作,不一定会打开网页。同时我需要检测点击坐标。我打算为此使用拖动手势处理程序。

我使用 AttributedString 将可点击文本实现为 links。 问题是我无法检测到点击坐标,因为点击 link.

时不会调用点击或拖动手势的处理程序

关于如何在 SwiftUI 中同时检测 link 和点击坐标的任何想法?

(我不想为此使用网络视图,因为我的应用程序是一个阅读应用程序,具有很多与文本相关的功能。)

下面是一个代码示例。我为我的应用程序定义了一个自定义 URL 方案,以便能够为 link 实现自定义处理程序。

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
    }
}

您需要使用 simultaneousGesture(_:including:)。这是因为您已经在单击 link,因此不会出现正常的手势。使用 simultaneousGesture 意味着您同时单击 link 并可以抓取坐标。

代码:

Text(makeAttributedString()).padding()
    .simultaneousGesture(
        /* ... */
    )