Как я могу применить свой пользовательский атрибут в атрибутивной строке в SwiftUI

#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. print Использует 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. эй, внес пару правок, чтобы было более ясно, что атрибуции носят чисто декоративный характер