在SwiftUI中编程插入内联图像

hgqdbh6s  于 2023-08-02  发布在  Swift
关注(0)|答案(2)|浏览(82)

我正在开发一个SwiftUI应用程序,我想在其中插入内联图像到Text视图。对于静态内容,我可以像这样使用字符串插值:

Text("Hello, \(Image(systemName: "pencil")) World! \(Image(systemName: "pencil.circle"))")

字符串
结果如下:


的数据
但在我的情况下,内容可能是动态的。也就是说,我可能会从服务器接收到以下字符串:

Hello #image(pencil) World! #image(pencil.circle)


我必须动态解析内容,并使用SwiftUI Text呈现内联图像。这可能吗?我只想知道如何动态地构造图像的字符串插值,字符串的解析不是我关心的问题。

c90pui9n

c90pui9n1#

你可以在初始化Image时传递一个变量:

var imageNameFromServer = "pencil"
Text("Hello, world \(Image(systemName: imageNameFromServer))")

字符串
更新:使用多个Text项目的示例:

@ViewBuilder
var longText: some View {
    (0...100).reduce(Text(""), { $0 + Text("\($1)")})
}

3lxsmp7m

3lxsmp7m2#

这是一个相当有趣的问题!这里有一个实现这一点的替代方法。

import SwiftUI

struct ContentView: View {
    var body: some View {
        let serverString = "Hello #image(pencil) World!     #image(pencil.circle)"
        
        parse(serverString).reduce(Text("")) { (result, model) in
            return result + model.getSwiftUIView()
        }
    }
    
    func parse(_ serverString: String) -> [Model] {
        serverString.split(separator: " ", omittingEmptySubsequences: false).compactMap {
            Model(word: String($0))
        }
    }
}

struct Model {
    enum ViewType {
        case image, text
    }
    
    let type: ViewType
    let content: String
    
    init(word: String) {
        if word.hasPrefix("#image") {
            type = .image
            content = Model.replaceImagePatterns(input: String(word))
        } else {
            type = .text
            content = word
        }
    }

    func getSwiftUIView() -> Text {
        if type == .image {
            return Text("\(Image(systemName: content))") + Text(" ")
        } else {
            return Text(content) + Text(" ")
        }
    }
    
    static func replaceImagePatterns(input: String) -> String {
        let pattern = "#image\\((\\w+(?:\\.\\w+)*)\\)"
        let replacement = "$1"

        do {
            let regex = try NSRegularExpression(pattern: pattern, options: [])
            let range = NSRange(location: 0, length: input.utf16.count)

            var modifiedString = input
            let matches = regex.matches(in: input, options: [], range: range)
            for match in matches.reversed() {
                if let range = Range(match.range, in: modifiedString) {
                    let matchedString = String(modifiedString[range])
                    let modifiedMatchedString = regex.stringByReplacingMatches(in: matchedString, options: [], range: NSRange(location: 0, length: matchedString.utf16.count), withTemplate: replacement)
                    modifiedString = modifiedString.replacingCharacters(in: range, with: modifiedMatchedString)
                }
            }

            return modifiedString
        } catch {
            print("Error creating regex: \(error)")
            return input
        }
    }
}

字符串

输入

第一个月

输出

x1c 0d1x的数据
我希望你发现答案有帮助。

相关问题