#ios #swiftui #uiviewrepresentable
Вопрос:
У меня была uiviewпредставляемая реализация для UITextView, позволяющая отображать и обрабатывать ссылки на
...
struct TextViewWrapper: UIViewRepresentable {
....
func makeUIView(context: Context) -> UITextView {
let textView = UITextView()
textView.text = text
textView.textColor = foregroundColor
textView.font = font
textView.backgroundColor = .white
textView.dataDetectorTypes = .link
textView.isEditable = false
textView.isSelectable = true
textView.isScrollEnabled = false
textView.delegate = context.coordinator
textView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
textView.isExclusiveTouch = true
recalculateHeight(view: textView, result: $calculatedHeight)
return textView
}
....
}
// Coordinator
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
onSelectLink(URL)
return false
}
...
Это используется в представлении SwiftUI следующим образом:
struct Content: View {
var body: some View {
VStack {
TextViewWrapper(text: "Text with link https://google.com", onSelectLink: { _ in print("On select link") })
}
.onTapGesture { print("On tap gesture") }
}
}
Примечание: Это упрощенный пример. Но проблема в том, что взаимодействие со ссылкой вызывает обратный вызов onSelectLink, но также позволяет выполнять распознаватель onTapGesture. Я ожидаю, что касание UITextView будет иметь приоритет, а onTapGesture будет проигнорировано.
Комментарии:
1. Зачем тогда вам нужен
onTapGesture
просмотр поверх текста? Просто удалите его из общегоVStack
и положите только туда, где ожидалось.2. @Asperi Просто для уточнения, компонент
VStack
является картой (модификатор крана предназначен для отображения деталей), внутри VStack есть больше просмотров. Я хочуTextViewWrapper
, чтобы захватить ссылки (shouldInteractWithLinks: UITextViewDelegate) и избежать срабатывания onTapGesture, но если пользователь нажмет на текст, который не является обнаруженной ссылкой (тогда это может позволить обработать нажатие с помощью карты ~ onTapGesture)
Ответ №1:
Возможное решение состоит в том, чтобы добавить onTapGesture
к TextViewWrapper
нему и игнорировать его:
VStack {
TextViewWrapper(text: "Text with link https://google.com", onSelectLink: { _ in print("On select link") })
.onTapGesture {
// ignore this tap
}
}.onTapGesture {
print("On tap gesture")
}
Комментарии:
1. Спасибо! Это решение, по крайней мере, исправит нажатие на ссылку, предотвращающую запуск жеста карты.