无法将 NSAttributedString.DocumentAttributeKey 类型的值转换为 .DocumentReadingOptionKey
Posted
技术标签:
【中文标题】无法将 NSAttributedString.DocumentAttributeKey 类型的值转换为 .DocumentReadingOptionKey【英文标题】:Cannot convert value of type NSAttributedString.DocumentAttributeKey to .DocumentReadingOptionKey 【发布时间】:2017-06-06 12:51:01 【问题描述】:我在 SO 的某处发现了这个字符串扩展,它允许我将 html 代码转换为属性字符串:
func html2AttributedString() -> NSAttributedString
return try! NSAttributedString(data: self.data(using: String.Encoding.unicode, allowLossyConversion: true)!, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil)
它在 Swift 3 中运行良好,但在 Swift 4 中,Xcode 抱怨:
无法将“NSAttributedString.DocumentAttributeKey”类型的值转换为预期的字典键类型“NSAttributedString.DocumentReadingOptionKey”
我该如何解决这个问题?
【问题讨论】:
【参考方案1】:您需要传递一个可用的 NSAttributedString DocumentType 选项:
超文本标记语言 (HTML) 文档。
static let html: NSAttributedString.DocumentType
纯文本文档。
static let plain: NSAttributedString.DocumentType
富文本格式文档。
static let rtf: NSAttributedString.DocumentType
带有附件文档的富文本格式。
static let rtfd: NSAttributedString.DocumentType
在这种情况下,您需要传递第一个 (html) NSAttributedString.DocumentType.html
所以 Swift 4 的扩展 updated 应该是这样的:
extension NSAttributedString
convenience init(data: Data, documentType: DocumentType, encoding: String.Encoding = .utf8) throws
try self.init(data: data,
options: [.documentType: documentType,
.characterEncoding: encoding.rawValue],
documentAttributes: nil)
convenience init(html data: Data) throws
try self.init(data: data, documentType: .html)
convenience init(txt data: Data) throws
try self.init(data: data, documentType: .plain)
convenience init(rtf data: Data) throws
try self.init(data: data, documentType: .rtf)
convenience init(rtfd data: Data) throws
try self.init(data: data, documentType: .rtfd)
extension StringProtocol
var data: Data return Data(utf8)
var htmlToAttributedString: NSAttributedString?
do
return try .init(html: data)
catch
print("html error:", error)
return nil
var htmlDataToString: String?
return htmlToAttributedString?.string
extension Data
var htmlToAttributedString: NSAttributedString?
do
return try .init(html: self)
catch
print("html error:", error)
return nil
游乐场测试
let htmlString = "<style type=\"text/css\">#redcolor:#F00#greencolor:#0F0#bluecolor: #00F; font-weight: Bold; font-size: 32</style><span id=\"red\" >Red</span><span id=\"green\" > Green </span><span id=\"blue\">Blue</span>"
let htmlData = Data(htmlString.utf8)
htmlString.htmlToAttributedString
htmlData.htmlToAttributedString
讨论 HTML 导入器不应该从后台调用 线程(即,选项字典包含带有 html 的值)。它将尝试与主线程同步,失败, 和超时。从主线程调用它有效(但仍然可以 如果 HTML 包含对外部资源的引用,则超时,这 应不惜一切代价避免)。 HTML 导入机制的意思 用于实现诸如降价之类的东西(即文本样式, 颜色等),不适用于一般的 HTML 导入
【讨论】:
这太棒了。我能够将 API 中的&#36
转换为 $。虽然它非常冗长。有没有更快捷的方式?谢谢。
试过了。这是一种清洗,因为它只消除了三个错误行catch, print, return
,但无论如何你必须在你的财产上使用String(describing:
。另外,我应该在使用 API 时进行错误检查。也许 Swift 5 会让我们用一种神奇的方法来做到这一点,比如encodeHTML
=P。
是的。功能是一样的。我想说的是,考虑到安全性的权衡,删除catch
、print
和return
是微不足道的。他们都工作。虽然很可怕:)
如果我在 25% 的时间调用此命令时得到一个僵尸,你会说我做错了什么?我没有明确地释放任何地方
我们不能添加 HTML 表格吗?例如let htmlTable = "<table> <tr> <th>Name</th> <th>Favorite Color</th> </tr> <tr> <td>Bob</td> <td>Yellow</td> </tr> <tr> <td>Michelle</td> <td>Purple</td> </tr> </table>"
【参考方案2】:
在自动转换为 Swift 4 后出现此问题。已通过更改:
NSMutableAttributedString(data: data,
options: [NSAttributedString.DocumentAttributeKey.documentType : NSAttributedString.DocumentType.html],
documentAttributes: nil)
到:
NSMutableAttributedString(data: data,
options: [.documentType : NSAttributedString.DocumentType.html],
documentAttributes: nil)
【讨论】:
这是解决方案。非常感谢【参考方案3】:这对我有用:
let attrStr = try! NSAttributedString(
data: modifiedFont.data(using: .unicode, allowLossyConversion: true)!,
options:[.documentType: NSAttributedString.DocumentType.html,
.characterEncoding: String.Encoding.utf8.rawValue],
documentAttributes: nil)
如果不添加
.characterEncoding: String.Encoding.utf8.rawValue
应用程序将崩溃。
【讨论】:
我怎样才能在其中给出 fontSize 和字体?【参考方案4】:swift 4:我不知道为什么所有答案对我来说都有编译器错误。所以使用这个扩展:
extension String
var html2AttributedString: NSAttributedString?
do
return try NSAttributedString(data: data(using: String.Encoding(rawValue: String.Encoding.utf8.rawValue))!,
options: [.documentType: NSAttributedString.DocumentType.html,
.characterEncoding: String.Encoding.utf8.rawValue],
documentAttributes: nil)
catch
print("error: ", error)
return nil
var html2String: String
return html2AttributedString?.string ?? ""
如何使用?
mylable.text = htmlVariable.html2String
【讨论】:
【参考方案5】:对于 HTML 字符串,NSAttributedString.DocumentType.html
是正确的选项。
斯威夫特 4
extension String
var utfData: Data?
return self.data(using: .utf8)
var htmlAttributedString: NSAttributedString?
guard let data = self.utfData else
return nil
do
return try NSAttributedString(data: data,
options: [
NSAttributedString.documentType: NSAttributedString.DocumentType.html,
NSAttributedString.characterEncoding: String.Encoding.utf8.rawValue
], documentAttributes: nil)
catch
print(error.localizedDescription)
return nil
【讨论】:
【参考方案6】:使用NSAttributedString.DocumentType.html
NSMutableAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html] , documentAttributes: nil)
【讨论】:
【参考方案7】:我使用 NSAttributedStringKey 并且在 Swift 4 上遇到了类似的错误“无法转换类型的值”。如果有人使用 NSAttributedStringKey 来这里寻找答案,我就是这样解决的:
let TextStroke: [NSAttributedStringKey : Any] = [
NSAttributedStringKey(rawValue: NSAttributedStringKey.strokeColor.rawValue) : UIColor.black,
NSAttributedStringKey(rawValue: NSAttributedStringKey.foregroundColor.rawValue) : UIColor.white,
NSAttributedStringKey(rawValue: NSAttributedStringKey.strokeWidth.rawValue) : -6.0,]
这就是我将属性添加到文本的方式:
myLabel.attributedText = NSAttributedString(string: myString, attributes: TextStroke)
【讨论】:
这太麻烦了。NSAttributedStringKey
的好处是避免那些冗长的初始化。你应该简单地写let textStroke: [NSAttributedStringKey : Any] = [.strokeColor : UIColor.black, .foregroundColor : UIColor.white, .strokeWidth : -6.0]
【参考方案8】:
Swift 4.x & 5.x
if let rtfPath = Bundle.main.url(forResource: "FileName", withExtension: "rtf")
do
let attributedString: NSAttributedString = try NSAttributedString(url: rtfPath, options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.rtf], documentAttributes: nil)
debugPrint(attributedString)
catch
print("Error while reading the file - \(error.localizedDescription)")
从文件中获取 NSAttributedString 将在 Swift 3.x 中进行更改,如下所示:
let attributedStringWithRtf: NSAttributedString = try NSAttributedString(url: rtfPath, options: [NSDocumentTypeDocumentAttribute:NSRTFTextDocumentType], documentAttributes: nil)
所有其他代码与 Swift 4.x 和 5.x 相同。
更多详情请阅读苹果NSAttributedStringDocumentType相关文档
【讨论】:
以上是关于无法将 NSAttributedString.DocumentAttributeKey 类型的值转换为 .DocumentReadingOptionKey的主要内容,如果未能解决你的问题,请参考以下文章
无法将 createdAt 和 updatedAt 保存为日期时间值,也无法将后端保存为前端
C# 无法将类型为“System.Byte[]”的对象强制转换为类型“System.Data.DataTable
无法将类型为“System.Collections.Generic.List`1[EPMS.Domain.SingleItem]”的对象强制转换为类型“EPMS