假设我有一个字符串:
这是一个<b>简单的</b>字符串。
我需要去掉 < b >,(抱歉 b 和尖括号之间没有空格,由于某种原因预览没有显示它),还要将“简单”这个词加粗,我的想法是:
- 用空格替换尖括号和 br
- 使“简单”段具有属性
问题是一旦标签被删除,我仍然需要知道单词的位置,我是不是先记住'simple'的位置,删除后location-4应该是'simple'的新位置?有没有更好的办法?甚至将 html 标签转换为属性?
谢谢
编辑:应该是 b 而不是 br
假设我有一个字符串:
这是一个<b>简单的</b>字符串。
我需要去掉 < b >,(抱歉 b 和尖括号之间没有空格,由于某种原因预览没有显示它),还要将“简单”这个词加粗,我的想法是:
问题是一旦标签被删除,我仍然需要知道单词的位置,我是不是先记住'simple'的位置,删除后location-4应该是'simple'的新位置?有没有更好的办法?甚至将 html 标签转换为属性?
谢谢
编辑:应该是 b 而不是 br
iOS 7 中有可用的 API 使这变得非常容易。它将NSString
(可能的)HTML 文本转换为NSAttributedString
.
NSDictionary *options = @{ NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType };
NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithData:[myHTMLString dataUsingEncoding:NSUTF8StringEncoding] options:options documentAttributes:nil error:nil];
它甚至会保留任何应用的内联 CSS,甚至background-color
!
请注意,如果 HTML 文本中未指定字体和字体大小,则默认值为 Times New Roman 12。您可以按以下方式指定:<style>body { font-family:-apple-system; font-size:14px; }<style>
. 如果您不通过 CSS 指定字体,您仍然可以覆盖字体,但您需要手动处理粗体、斜体等,否则如果您为整个字符串设置字体,格式将丢失。一种方法是enumerateAttribute: NSFontAttributeName
在可变属性字符串上查找字体名称中的“粗体”等,如果找到,则将其替换range
为所需的字体,例如用户的首选字体和大小,但它的粗体等版本,然后继续用range
从枚举中获得的每个替换字体。
目前的答案是好的,我已经 +1 了。然而,这只是一个线索,而不是真正的解决方案。如果您正在寻找 OP 问题的解决方案,请查看此处。
您应该关注以下内容:
首先实现这些方法:
- (NSString *)styledHTMLwithHTML:(NSString *)HTML {
NSString *style = @"<meta charset=\"UTF-8\"><style> body { font-family: 'HelveticaNeue'; font-size: 20px; } b {font-family: 'MarkerFelt-Wide'; }</style>";
return [NSString stringWithFormat:@"%@%@", style, HTML];
}
- (NSAttributedString *)attributedStringWithHTML:(NSString *)HTML {
NSDictionary *options = @{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType };
return [[NSAttributedString alloc] initWithData:[HTML dataUsingEncoding:NSUTF8StringEncoding] options:options documentAttributes:NULL error:NULL];
}
以后像这样使用它们:
// This is a string that you might find in your model
NSString *html = @"This is <b>bold</b>";
// Apply some inline CSS
NSString *styledHtml = [self styledHTMLwithHTML:html];
// Generate an attributed string from the HTML
NSAttributedString *attributedText = [self attributedStringWithHTML:styledHtml];
// Set the attributedText property of the UILabel
label.attributedText = attributedText;
使用此方法(Swift 5):
extension Swift {
// Color all strings between two tags and remove the tags
mutating func colorSubstringsBetweenTags(start: String, end: String, color: UIColor, font: UIFont? = nil) -> NSAttributedString {
var string = self
let attribute = NSMutableAttributedString(string: string)
while let openedEm = string.range(of: start, range: string.startIndex..<string.endIndex) {
let substringFrom = openedEm.upperBound
guard let closedEm = string.range(of: end, range: openedEm.upperBound..<string.endIndex) else { return attribute }
let substringTo = closedEm.lowerBound
let nsrange = NSRange(substringFrom..<substringTo, in: string)
if let font = font { attribute.addAttributes([.font: font], range: nsrange) }
attribute.addAttribute(.foregroundColor, value: color, range: nsrange)
attribute.mutableString.replaceCharacters(in: NSRange(closedEm, in: string), with: "")
attribute.mutableString.replaceCharacters(in: NSRange(openedEm, in: string), with: "")
string = attribute.mutableString as String
}
return attribute
}
}
用法:
var text = "some text with <b>tags</b> or other <b>TAG</b>"
yourLabel.attributedText = text.colorSubstringsBetweenTags(start: "<b>", end: "</b>", color: .red)
类似于迈克尔刚刚为最新的快速版本更新的答案,
extension UILabel {
func setHTMLFromString(htmlText: String) {
// Apply some inline CSS
let style = "<meta charset=\"UTF-8\"><style> body { font-family: 'TheSansArabic-Plain'; font-size: 12px; } b {font-family: 'TheSansArabic-Bold'; font-size: 12px; } </style>"
let styledHtml = style + htmlText
// Generate an attributed string from the HTML
let attributedText = try? NSAttributedString(data: styledHtml.data(using: .utf8)!, options: [.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil)
// Set the attributedText property of the UILabel
self.attributedText = attributedText
}
}
像这样在你的代码中使用,
override func viewDidLoad() {
super.viewDidLoad()
label.setHTMLFromString(htmlText: "This is <b>BOLD text</b>")
}