#swift #swiftui
Вопрос:
У меня здесь есть свой пользовательский атрибут, просто для тестирования, цель состоит в том, чтобы поменять местами буквы, просто чтобы посмотреть, как я могу повлиять на строку
enum SwapAttribute : AttributedStringKey { typealias Value = String static let name = "swap" } extension AttributeScopes { struct MyTextStyleAttributes: AttributeScope { let swap: SwapAttribute } } extension AttributeDynamicLookup { subscriptlt;T: AttributedStringKeygt;(dynamicMember keyPath: KeyPathlt;AttributeScopes.MyTextStyleAttributes, Tgt;) -gt; T { return self[T.self] } } func attributesTest() { var str = AttributedString("It's a secret") let secret = str.range(of: "secret")! str[secret].swap = "*" // expect 'It's a ******' print(str) }
Я могу добавить свой атрибут, и я могу видеть его в .runs
переменной, но вся документация и учебные пособия замалчивают это. Как мне выполнить код или применить изменения к строке.
(или, возможно, это предназначено для других целей)
Комментарии:
1.
AttributedString.description
для вывода, который ничего не знает об обработке вашего пользовательского атрибута. Вы можете добавлять пользовательские атрибуты, но только для ваших целей, т. Е. ваш код будет обрабатывать это — все внутреннее не будет заботиться об этом.
Ответ №1:
Пользовательские Реализации
Пользовательские атрибуты служат только для хранения данных, они не отображаются и не обрабатываются SwiftUI или UIKit. Дополнительное пользовательское поведение должно быть реализовано вручную.
Обходной путь
Для поведения, описанного в вопросе, придерживайтесь расширений.
var str = AttributedString("It's a ******") let secret = str.range(of: "******")! str[secret].swap = "secret"
Это будет отображать «Это ******», сохраняя при этом ваши «секретные» данные в атрибутах.
Чтобы улучшить это, вы можете создать расширение:
extension AttributedString { func swapping(_ value: String, with new: Character) -gt; AttributedString { let mutableAttributedString = NSMutableAttributedString(self) let range = mutableAttributedString.mutableString.range(of: value) let newString = String(repeating: new, count: range.length) // Use replaceCharacters(in:with:) to keep all original attributes mutableAttributedString.replaceCharacters(in: range, with: newString) // Set the "secret" data var str = AttributedString(mutableAttributedString) str[str.range(of: newString)!].swap = value return str } } var str = AttributedString("It's a secret") .swapping("secret", with: "*") print(str)
Вывод на печать:
It's a { } ****** { swap = secret }
Комментарии:
1. эй, внес пару правок, чтобы было более ясно, что атрибуции носят чисто декоративный характер