我有一个字符串"Hello {world}"
,我需要用"Hello "
替换它。占位符的位置不固定在末尾。我可能有不止一个占位符。
我正在使用SwiftUI,并试图使此工作与
Text("Hello {world}".replacingOccurrences(of: "{world}", with: "\(Image(systemName: "globe"))"))
但很快就发现这是不可行的,并提出了这个Hello Image(provider: SwiftUI.ImageProviderBox<SwiftUI.Image.(unknown context at $1ba606db0).NamedImageProvider>)
因为这起作用了
Text(LocalizedStringKey("Hello \(Image(systemName: "globe"))"))
我认为我需要将一个LocalizedStringKey
传递到我再次尝试的Text
中。
Text(LocalizedStringKey("Hello {world}".replacingOccurrences(of: "{world}", with: "\(Image(systemName: "globe"))")))
Text(LocalizedStringKey("Hello" + "\(Image(systemName: "globe"))")) //this doesn't work either
但是有一个类似的问题-- SwiftUI.Text.Storage.anyTextStorage(SwiftUI.(unknown context at $1ba668448).LocalizedTextStorage
我查看了LocalizedStringKey
和LocalizedStringKey.StringInterpolation
的API,但是找不到解决这个问题的方法。是否有办法使占位符字符串的替换工作?
发布于 2022-09-21 15:27:44
这是对@jrturton的回答的一个小改进,它根据我的需要进行了调整。也许这会让其他人受益。然而,这与我最初的回答有很大的不同,所以我有理由把它作为一个新的答案来补充。deletingPrefix
来自轻快地
import PlaygroundSupport
import Foundation
import SwiftUI
extension String {
func deletingPrefix(_ prefix: String) -> String {
guard self.hasPrefix(prefix) else { return self }
return String(self.dropFirst(prefix.count))
}
}
extension LocalizedStringKey {
@available(iOS 15, *)
init(imageText: String, replacementClosure: (String) -> Any) {
var components = [Any]()
var length = 0
let scanner = Scanner(string: imageText)
scanner.charactersToBeSkipped = nil
while scanner.isAtEnd == false {
let up = scanner.scanUpToString("{")
let start = scanner.scanString("{")
let name = scanner.scanUpToString("}")
let end = scanner.scanString("}")
if let up = up {
components.append(up)
length += up.count
}
if let name = name {
if start == nil || end == nil { self.init(stringLiteral: imageText) }
let replacement = replacementClosure(name)
switch replacement {
case let image as Image:
components.append(image)
case let attributedString as AttributedString:
components.append(attributedString)
case let plainString as String:
components.append(plainString)
default:
print("No action.")
}
}
}
var interp = LocalizedStringKey.StringInterpolation(literalCapacity: length, interpolationCount: components.count)
for component in components {
if let string = component as? String {
interp.appendInterpolation(string)
}
if let attrString = component as? AttributedString {
interp.appendInterpolation(attrString)
}
if let image = component as? Image {
interp.appendInterpolation(image)
}
}
self.init(stringInterpolation: interp)
}
}
extension Text {
init(imageText: String) {
self.init(LocalizedStringKey(imageText: imageText, replacementClosure: { string in
switch string {
case "world":
return Image(systemName: "globe")
case "moon":
return Image(systemName: "moon")
case let stylisedString where stylisedString.hasPrefix("style1__"):
return AttributedString(stylisedString.deletingPrefix("style1__"), attributes: AttributeContainer().foregroundColor(.blue))
default: return string
}
}))
}
}
PlaygroundPage.current.setLiveView(Text(imageText: "Hello {world}! or {moon} or {style1__unmapped}")
)
https://stackoverflow.com/questions/73742578
复制相似问题