Создание рекурсивного текстового представления в SwiftUI
Моя цель - создать представление SwiftUI, которое принимает строку и автоматически форматирует этот текст в текстовые представления. Часть строки, требующая форматирования, определяется с помощью регулярного выражения, а затем возвращается как Range<String.Index>. Это можно использовать для восстановления String после применения форматирования к соответствующим текстовым представлениям. Поскольку может быть несколько экземпляров текста, которые необходимо отформатировать, запуск функции форматирования должен выполняться рекурсивно.
struct AttributedText: View {
@State var text: String
var body: some View {
AttributedTextView(text: text)
}
@ViewBuilder
private func AttributedTextView(text: String) -> some View {
if let range = text.range(of: "[0-9]+d[0-9]+", options: .regularExpression) {
//The unattributed text
Text(text[text.startIndex..<range.lowerBound]) +
//Append the attributed text
Text(text[range]).bold() +
//Search for additional instances of text that needs attribution
AttributedTextView(text: String(text[range.upperBound..<text.endIndex]))
} else {
//If the searched text is not found, add the rest of the string to the end
Text(text)
}
}
Я получаю ошибку
Cannot convert value of type 'some View' to expected argument type 'Text'
, с рекомендуемым исправлением, чтобы обновить рекурсивную строку до
AttributedTextView(text: String(text[range.upperBound..<text.endIndex])) as! Text
. Я применяю это исправление, но по-прежнему вижу ту же ошибку компилятора с тем же предложенным исправлением.
Несколько способов обхода, которые я пробовал:
- Изменение типа возврата с
some View
кText
. Это создает другую ошибкуCannot convert value of type '_ConditionalContent<Text, Text>' to specified type 'Text'
. Я особо не исследовал это дальше, так как имеет смысл, что возвращаемое значение зависит от этого условия. - Возврат группы, а не текста, что вызывает дополнительные ошибки во всем файле SwiftUI
Ни одно из этих решений не кажется «быстрым». Что можно сделать по-другому? Я что-то неправильно понимаю в SwiftUI?
1 ответ
Здесь нужно уточнить несколько моментов:
В
+
перегрузка работает только между
Texts
поэтому он говорит, что не может преобразовать (ваш возвращаемый тип) в. + ==, +
some View
==
☠️
Изменение типа возврата на вас не работает, потому что вы используете, remove, и он будет работать нормально.
Почему? позволяет
SwiftUI
чтобы отложить оценку закрытия на потом, но гарантирует, что это приведет к определенному типу представления (не AnyView). В случае, если ваше закрытие возвращает либо a, либо
Image
это удобно, но в вашем случае, когда это всегда приводит к
Text
в этом нет необходимости ,
@ViewBuilder
заставляет возвращаемый тип быть
ConditionalContent<Text, Text>
чтобы он мог иметь разные типы.
Вот что должно работать:
private static func attributedTextView(text: String) -> Text {
if let range = text.range(of: "[0-9]+d[0-9]+", options: .regularExpression) {
//The unattributed text
return Text(text[text.startIndex..<range.lowerBound]) +
//Append the attributed text
Text(text[range]).bold() +
//Search for additional instances of text that needs attribution
AttributedTextView(text: String(text[range.upperBound..<text.endIndex]))
} else {
//If the searched text is not found, add the rest of the string to the end
return Text(text)
}
}
Я тоже сделал его статическим, потому что здесь нет состояния, это чистая функция и сделал его в нижнем регистре, чтобы было ясно, что это функция, а не тип (имя функции выглядит как
View
тип).
Вы бы просто назвали это
Self.attributedTextView(text: ...)