来自 HTML (Swift 4) 的属性文本中的字符串插值

String interpolation in attributed text from HTML (Swift 4)

我在我的应用程序中将文本显示为来自本地 HTML 文件的属性字符串,填充标签,因为这为我提供了格式化灵活性。为什么通常的字符串插值在这种情况下不起作用,有解决方法吗?目的是允许用户提供的用户名包含在字符串中。除了在标签中显示的 HTML 文件中留下“(user)”而不是像我预期的那样插入用户名外,它运行良好。我还在学习,所以如果这是一种奇怪且不可行的做事方式,请告诉我...

这是我的代码:

class ArticleViewController: UIViewController {

    @IBOutlet weak var contentField: UITextView!

    var articleID : String = ""

    var user = UserDefaults.standard.object(forKey: "user") ?? "user"

    override func viewDidLoad() {
        super.viewDidLoad()

        if let html = Bundle.main.path(forResource: "\(articleID)", ofType: "html") {
            let urlToLoad = URL(fileURLWithPath: html)
            let data = NSData(contentsOf: urlToLoad)

            if let attributedString = try? NSAttributedString(data: data as! Data, options: [.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil) {

                contentField.attributedText = attributedString

            }
        }
    } 
}

感谢您的帮助!

您必须找到并替换 attributedString 中出现的 (user)

这应该有效:

import Foundation
import UIKit

var myString : NSAttributedString = NSAttributedString(string: "Hello (user), this is a message for you")
let regex = try! NSRegularExpression(pattern: "\(user\)", options: .caseInsensitive)
let range = NSMakeRange(0, myString.string.count)
let newString = regex.stringByReplacingMatches(in: myString.string, options: [], range: range, withTemplate: "CJDSW18")
let newAttribuetdString = NSAttributedString(string: newString, attributes: myString.attributes(at: 0, effectiveRange: nil))
print(newAttribuetdString.string)

为什么通常的字符串插值在这种情况下不起作用

通常的字符串插值适用于 Swift 源文件中的字符串文字,不适用于一般文本文件或 html 文件的内容。

您可能需要替换属性字符串中出现的 (user)。 (基本概念和Carpsen90的回答没有区别,但是替换已经属性化的字符串时需要小心。)

    if let htmlURL = Bundle.main.url(forResource: articleID, withExtension: "html") {
        do {
            let data = try Data(contentsOf: htmlURL)

            let attributedString = try NSMutableAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil)

            //### When you want to compare the result...
            //originalText.attributedText = attributedString

            let regex = try! NSRegularExpression(pattern: "\(user\)")
            let range = NSRange(0..<attributedString.string.utf16.count)
            let matches = regex.matches(in: attributedString.string, range: range)
            for match in matches.reversed() {
                attributedString.replaceCharacters(in: match.range, with: user)
            }

            contentField.attributedText = attributedString
        } catch {
            // Do error processing here...
            print(error)
        }
    }

示例。

article.html:

<html>
<head>
    <meta charset="utf-8">
</head>
<body>
    <i>(user)</i><b>(user)</b>
</body>
</html>

您在文本视图中可以看到的内容: