Использование URL-адреса для отображения всех параметров системы для номера телефона в Swift - PullRequest
1 голос
/ 05 августа 2020

Swift имеет класс под названием UITextView, у которого есть свойство под названием dataDetectorTypes, которое будет автоматически сканировать текст на предмет указанных типов данных (например, телефонных номеров, местоположений карт и т. Д. c.), Выделять найденные вхождения и предоставлять варианты взаимодействия с пользователем. В настоящее время я перевожу свое приложение на использование SwiftUI и изо всех сил пытаюсь реализовать специфическое c поведение детектора данных. А именно, когда телефонный номер нажимается, он предлагает возможность позвонить, но при принудительном нажатии (или, как я предполагаю, долгом нажатии) он предлагает несколько вариантов со всей системы, от приложений для обмена сообщениями от собственных до сторонних. Следующие два изображения показывают, о чем я говорю:

Вариант вызова при нажатии Call option on tap

System wide options on force touch Общесистемные параметры Force Touch

Я попытался обернуть UITextView внутри UIViewRepresentable, и это работает по большей части, но это некрасиво и делает интеграцию с остальной частью приложения немного более сложной. И в конце концов, как я его использую, на самом деле нет необходимости во всей мощи UITextView. На самом деле это просто кнопка со ссылкой.

Я не уверен, какой элемент SwiftUI использовать, но высказал следующие соображения:

  • Text: хотя я не Я думаю, что это может справиться с взаимодействием с пользователем
  • Link: это может быть актуально, но это означает, что мне нужно установить минимальное требование iOS 14
  • Button: этот параметр кажется наиболее многообещающим. Используя другие ответы SO, у меня есть что-то вроде этого:
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)

Однако это обеспечивает только первое поведение, возможность вызова при нажатии, а не второе поведение. Есть ли способ составить URL-адрес телефона в Swift, чтобы открыть несколько параметров, сгенерированных системой? Или мне следует сделать что-то другое, используя другую функцию Xcode?

1 Ответ

1 голос
/ 05 августа 2020

AFAIK, нет возможности получить программный доступ к этой таблице действий системы. Вероятно, вы могли бы попробовать скопировать все кнопки одну за другой, но, честно говоря, я бы просто использовал UITextView, завернутый в UIViewRepresentable.

Какие у вас проблемы с этим? У меня возникли проблемы с макетом, которые были решены с помощью представления SwiftUI Text в качестве шаблона.

Ниже приведен класс, который я использовал. Он обнаруживает все типы данных, но вы можете легко изменить его, чтобы просто определять номера телефонов.

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()
    }
}
...