首页 > 解决方案 > 使用 URL 在 Swift 中显示电话号码的所有系统选项

问题描述

Swift 有一个名为 的类UITextView,它有一个名为 的属性dataDetectorTypes,它会自动扫描文本以查找指定的数据类型(如电话号码、地图位置等),突出显示找到的事件,并提供用户交互选项。我目前正在将我的应用程序转换为使用 SwiftUI,并且正在努力重新实现数据检测器的特定行为。也就是说,当一个电话号码被点击时,它会提供呼叫选项,但是当强制触摸(或者我假设长按)时,它会提供来自整个系统的多个选项,从第一方消息应用程序到第三方应用程序。以下两张图片显示了我所指的内容:

点击通话选项 点击通话选项

强制触摸的系统范围选项 强制触摸的系统范围选项

我尝试过将UITextView内部包裹起来UIViewRepresentable,这在大多数情况下都有效,但它很丑陋,并且与应用程序的其余部分集成变得更加棘手。毕竟,按照我使用它的方式,实际上并不需要UITextView. 它实际上只是一个带有链接的按钮。

我不确定要使用什么 SwiftUI 元素,但给出了以下注意事项:

Button("Click Me") {
    guard let url = URL(string: "telprompt://\(self.phoneString)"),
    UIApplication.shared.canOpenURL(url) else { return }
    UIApplication.shared.open(url, options: [:], completionHandler: nil)
}.foregroundColor(.blue)

然而,这只实现了第一个行为,即点击调用的选项,而不是第二个行为。有没有办法在 Swift 中编写电话 URL 以打开多个系统生成的选项?或者我应该做一些不同的事情,使用不同的 Xcode 函数?

标签: iosswiftxcodeswiftui

解决方案


AFAIK,无法以编程方式访问该系统操作表。您可能会尝试一个一个地复制所有按钮,但老实说,我只会使用一个UITextView包裹在UIViewRepresentable.

你有什么问题?我遇到了一些布局问题,通过使用 SwiftUIText视图作为模板解决了这些问题。

下面是我正在使用的课程。它检测所有类型的数据,但您可以轻松修改它以仅检测电话号码。

struct DataDetectorText: View {
    let text: String

    init(_ text: String) {
        self.text = text
    }

    var body: some View {
        Text(text + "\n")
            .fixedSize(horizontal: false, vertical: true)
            .hidden()
            .overlay(DataDetectorTextView(text: text))
    }
}

private struct DataDetectorTextView: UIViewRepresentable {
    let text: String

    func makeUIView(context _: Context) -> UITextView {
        let view = UITextView()

        view.text = text
        view.font = UIFont.preferredFont(forTextStyle: .body)

        view.dataDetectorTypes = [.all]
        view.isEditable = false
        view.isSelectable = true

        view.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
        view.isScrollEnabled = false
        view.textContainer.lineFragmentPadding = 0
        return view
    }

    func updateUIView(_ uiView: UITextView, context _: Context) {
        uiView.text = text
        uiView.sizeToFit()
    }
}

推荐阅读