首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何用SwiftUI中的图像替换占位符文本?

如何用SwiftUI中的图像替换占位符文本?
EN

Stack Overflow用户
提问于 2022-09-16 09:16:04
回答 5查看 182关注 0票数 2

我有一个字符串"Hello {world}",我需要用"Hello "替换它。占位符的位置不固定在末尾。我可能有不止一个占位符。

我正在使用SwiftUI,并试图使此工作与

代码语言:javascript
运行
复制
Text("Hello {world}".replacingOccurrences(of: "{world}", with: "\(Image(systemName: "globe"))"))

但很快就发现这是不可行的,并提出了这个Hello Image(provider: SwiftUI.ImageProviderBox<SwiftUI.Image.(unknown context at $1ba606db0).NamedImageProvider>)

因为这起作用了

代码语言:javascript
运行
复制
Text(LocalizedStringKey("Hello \(Image(systemName: "globe"))"))

我认为我需要将一个LocalizedStringKey传递到我再次尝试的Text中。

代码语言:javascript
运行
复制
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

我查看了LocalizedStringKeyLocalizedStringKey.StringInterpolation的API,但是找不到解决这个问题的方法。是否有办法使占位符字符串的替换工作?

EN

Stack Overflow用户

发布于 2022-09-21 15:27:44

这是对@jrturton的回答的一个小改进,它根据我的需要进行了调整。也许这会让其他人受益。然而,这与我最初的回答有很大的不同,所以我有理由把它作为一个新的答案来补充。deletingPrefix来自轻快地

代码语言:javascript
运行
复制
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}")
)
票数 0
EN
查看全部 5 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73742578

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档