ext将html代码转为字符串,在iOS中将HTML转换为NSAttributedString

2023-05-16

在iOS 7中,UIKit添加了一个initWithData:options:documentAttributes:error:方法,它可以使用HTML初始化NSAtttributedString,例如:

[[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUTF8StringEncoding] options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)} documentAttributes:nil error:nil];

Oliver Drobnik在Github上还有一个工作进行中的开源项目,除了NSAttributedString 。 它使用NSScanner进行HTMLparsing。

从HTML创buildNSAttributedString必须在主线程上完成!

更新:事实certificate,NSAttributedString HTML呈现取决于WebKit的底线, 必须在主线程上运行, 否则偶尔会使应用程序崩溃SIGTRAP 。

New Relic崩溃日志:

acbc6425f98af395f303b9453cccea85.png

下面是一个更新的线程安全的 Swift 2string扩展:

extension String { func attributedStringFromHTML(completionBlock:NSAttributedString? ->()) { guard let data = dataUsingEncoding(NSUTF8StringEncoding) else { print("Unable to decode data from html string: \(self)") return completionBlock(nil) } let options = [NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: NSNumber(unsignedInteger:NSUTF8StringEncoding)] dispatch_async(dispatch_get_main_queue()) { if let attributedString = try? NSAttributedString(data: data, options: options, documentAttributes: nil) { completionBlock(attributedString) } else { print("Unable to create attributed string from html string: \(self)") completionBlock(nil) } } } }

用法:

let html = "

Here is some HTML
" html.attributedStringFromHTML { attString in self.bodyLabel.attributedText = attString }

输出:

08c3cc78644a957afbf4747a34525aa6.png

这是一个在Swift中编写的String扩展,用于将HTMLstring作为NSAttributedString返回。

extension String { func htmlAttributedString() -> NSAttributedString? { guard let data = self.dataUsingEncoding(NSUTF16StringEncoding, allowLossyConversion: false) else { return nil } guard let html = try? NSMutableAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil) else { return nil } return html } }

要使用,

label.attributedText = "Hello \u{2022} babe".htmlAttributedString()

在上面,我故意添加了一个unicode \ u2022来表明它正确渲染unicode。

一个微不足道的: NSAttributedString使用的默认编码是NSUTF16StringEncoding (而不是UTF8!)。

NSAttributedString上的Swift初始值设定项扩展

我的意思是把这个扩展添加到NSAttributedString而不是String 。 我试过它作为一个静态的扩展和初始化。 我更喜欢下面包含的初始化程序。

斯威夫特4

extension NSAttributedString { internal convenience init?(html: String) { guard let data = html.data(using: String.Encoding.utf16, allowLossyConversion: false) else { return nil } guard let attributedString = try? NSMutableAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil) else { return nil } self.init(attributedString: attributedString) } }

Swift 3

extension NSAttributedString { internal convenience init?(html: String) { guard let data = html.data(using: String.Encoding.utf16, allowLossyConversion: false) else { return nil } guard let attributedString = try? NSMutableAttributedString(data: data, options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil) else { return nil } self.init(attributedString: attributedString) } }

let html = "Hello World!" let attributedString = NSAttributedString(html: html)

Swift 3.0 Xcode 8版本

func htmlAttributedString() -> NSAttributedString? { guard let data = self.data(using: String.Encoding.utf16, allowLossyConversion: false) else { return nil } guard let html = try? NSMutableAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil) else { return nil } return html }

你现在唯一的解决scheme是parsingHTML,使用给定的point / font / etc属性构build一些节点,然后将它们组合成一个NSAttributedString。 这是很多工作,但是如果做得对,将来可以重复使用。

对Andrew的解决scheme进行了一些修改,并将代码更新到Swift 3:

此代码现在使用UITextView作为self并能够inheritance其原始字体,字体大小和文本颜色

注意: toHexString()是来自这里的扩展

extension UITextView { func setAttributedStringFromHTML(_ htmlCode: String, completionBlock: @escaping (NSAttributedString?) ->()) { let inputText = "\(htmlCode)" guard let data = inputText.data(using: String.Encoding.utf16) else { print("Unable to decode data from html string: \(self)") return completionBlock(nil) } DispatchQueue.main.async { if let attributedString = try? NSAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil) { self.attributedText = attributedString completionBlock(attributedString) } else { print("Unable to create attributed string from html string: \(self)") completionBlock(nil) } } } }

用法示例:

mainTextView.setAttributedStringFromHTML("Hello world!") { _ in }

以上解决scheme是正确的。

[[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUTF8StringEncoding] options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)} documentAttributes:nil error:nil];

但是,如果你在ios 8.1,2或3上运行应用程序wioll崩溃。

为了避免崩溃,你可以做的是:在队列中运行。 所以它总是在主线上。

Swift 3 :

试试这个 :

extension String { func htmlAttributedString() -> NSAttributedString? { guard let data = self.data(using: String.Encoding.utf16, allowLossyConversion: false) else { return nil } guard let html = try? NSMutableAttributedString( data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil) else { return nil } return html } }

并用于:

let str = "

Hello bro

Come On

Go sis

  • ME 1
  • ME 2

It is me bro , remember please

" self.contentLabel.attributedText = str.htmlAttributedString()

有用的扩展

在iOS Gourmet Cookbook第80页的这个主题,一个pod和Erica Sadun的ObjC例子的启发下,我写了一个关于String和NSAttributedString的扩展,以便在HTML纯string和NSAttributedStrings之间来回切换,反之亦然 – 在GitHub上,我发现有帮助。

签名 (同上,链接上面的完整代码):

extension NSAttributedString { func encodedString(ext: DocEXT) -> String? static func fromEncodedString(_ eString: String, ext: DocEXT) -> NSAttributedString? static func fromHTML(_ html: String) -> NSAttributedString? // same as above, where ext = .html } extension String { func attributedString(ext: DocEXT) -> NSAttributedString? } enum DocEXT: String { case rtfd, rtf, htm, html, txt }

使用NSHTMLTextDocumentType很慢,很难控制样式。 我build议你去尝试一下我的图书馆,叫做Atributika。 它有自己的非常快速的HTMLparsing器。 你也可以有任何标签名称并为其定义任何样式。

例:

let str = "Hello World!".style(tags: Style("strong").font(.boldSystemFont(ofSize: 15))).attributedString label.attributedText = str

你可以在这里findhttps://github.com/psharanda/Atributika

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ext将html代码转为字符串,在iOS中将HTML转换为NSAttributedString 的相关文章

  • 在带有 Storyboard 的 XCode 4 中以模态方式推送视图时,出现“对开始/结束外观转换的不平衡调用”警告

    在网上进行了一些研究但没有成功后 我来这里向您询问有关我的警告的问题 实际上 我有一个带有导航控制器的视图 V1 我想在 V1 完成加载时推送模态视图 V2 所以我用performSegueWithIdentifier方法 我正在使用故事板
  • 为什么我不能在 Realm 属性上使用 private

    我正在尝试在 RealmSwift 中存储一个枚举案例 但 Realm 不支持枚举 本文 https medium com it works locally persisting swift enumerations with realm
  • 如何使用文件输入在PDFJS中打开本地PDF?

    我想知道是否有办法使用选择pdf文件input type file 并使用打开它PDFJS https github com mozilla pdf js 您应该能够使用 FileReader 来获取文件对象的内容作为类型化数组 pdfjs
  • 我应该使用哪种文档类型?

    如果我想使用可定制的 div 我应该使用哪种文档类型 具有div动画 图像移动 设置div不透明度等 我尝试通过 javascript 创建一个 div 设置其背景颜色 位置 宽度和高度 并向其添加 onmouseover 事件 一切正常
  • Django:使用条件 {% extends %} 使 {% block "div" %} 成为条件

    我想分享一个 AJAX 和常规 HTTP 调用之间的模板 唯一的区别是一个模板需要扩展 base html html 而另一个则不需要 我可以用 extends request is ajax yesno app base ajax htm
  • 推入 UINavigationController 时隐藏 FBFriendPickerViewController 导航栏

    介绍一个实例FBFriendPickerViewController using presentViewController animated completion 非常简单 该类似乎是针对该用例的 但是 我想推送一个实例FBFriendP
  • 如何处理 Django 中的错误

    我想让我的 django 应用程序尽可能对用户友好 并且我想处理适当的错误并让它推出类似于 javascript 中的警报的错误消息 我想在没有上传文件时执行此操作 因此 当按下上传按钮并且尚未上传任何内容时 将会发出一条警报消息 我的看法
  • 添加自定义过渡会导致 xib 加载错误的屏幕尺寸

    我正在尝试向具有 xib 的 UIViewController 添加自定义过渡 我尝试了几种方法 但它们都有相同的问题 视图显示的屏幕尺寸错误 我当前的示例基于以下教程 使用 Swift 在 iOS 中自定义 UIViewControlle
  • 如何恢复消耗品应用内购买?

    我正在开发一款 iOS 游戏 用户可以通过应用内消耗品购买一定数量的内部货币 比如 1000 金币 如果用户想将余额从一台设备转移到另一台设备 如何恢复消耗品购买 在苹果的文档中 它说我们必须使用我们自己的服务器 但是如何获取用户的Appl
  • iOS:提高图像绘制速度

    我有一系列想要制作动画的图像 UIImageView支持一些基本的动画 但不足以满足我的需求 我的第一个方法是使用UIImageView并设置image当图像属性 这太慢了 速度慢的原因是图像的绘制 这让我感到惊讶 我以为瓶颈会加载图像 我
  • 设置双指缩放时精确的滚动位置

    我正在创建一个地图应用程序 它将标记图像放置在画布上并滚动到它 我正在使用浏览器的捏缩放和滚动来放大 缩小地图 然而 我注意到有一些奇怪的行为 我想知道如何解决它 这有点难以解释 但我们开始吧 假设您处于网页的标准缩放级别 无法进一步缩小
  • 将html数据解析成python列表进行操作

    我正在尝试读取 html 网站并提取其数据 例如 我想查看公司过去 5 年的 EPS 每股收益 基本上 我可以读入它 并且可以使用 BeautifulSoup 或 html2text 创建一个巨大的文本块 然后我想搜索该文件 我一直在使用
  • 更改API数据输出的布局

    我是 API 集成和 PHP 的新手 我最近将 VIN 解码器集成到我的应用程序中 在输入框中输入车辆的 VIN 选择提交 然后就会显示 API 数据库中有关该车辆的所有信息 数据存储为关联数组 其中包含类别及其相应元素 例如 对于 VIN
  • 如何转义 HTML 字符?在.NET中-->“

    如何在 NET 中转义 HTML 字符 我正在从 json 字符串中获取 html 并在标题中得到 amp quot more text 看起来我需要做两次才能得到 amp quot 成为 quot 那么它就是一个 如何转义 NET 中的所
  • iphone:如何停止快门动画?

    我有两个问题 1 我想知道如何在相机加载时停止快门动画 我正在使用 UIImagePickerController 我已经参考了堆栈溢出的许多答案 但没有成功 2 我在相机中有一个自定义按钮 使用cameraOverlayView并想通过单
  • 在现有 iOS 应用程序中集成 React-native(0.40.0) 后找不到 Yoga/Yoga.h 头文件

    在我的 Swift iOS 应用程序中集成 React Native 后 我无法构建 yoga Yoga h file cannot be found 我已经浏览了文档 查看了react native github页面 检查了类似问题的SO
  • UIWebView Bug:-[UIWebView cut:]:无法识别的选择器发送到实例

    In the UIWebView 如果包含文本的输入元素具有焦点 并且按下按钮导致输入失去焦点 则随后双击输入以重新获得焦点并从出现的弹出栏中选择 剪切 或 复制 或 粘贴 会导致这UIWebView因错误而崩溃 UIWebView cut
  • 如何反转 CGPath 的点顺序

    我想画一个圆圈 并用它打出字母 为此 我需要顺时针抚摸圆圈 逆时针抚摸字母 这一切都很好 但是当我使用 Core Text 获取字母路径时 我不知道如何从本质上反转该路径 不是镜像或旋转或任何东西 这很简单 我希望点笔画顺序是逆时针的 这实
  • 在故事板中的视图控制器之间滑动手势

    我希望添加左右滑动手势来在视图控制器之间进行更改 这是否可能 并且有没有一种简单的方法可以在故事板中执行此操作 谢谢 故事板允许您在两个视图控制器之间设置 Segues 我想说首先在视图之间附加 Segues 给它一个标识符 然后使用类似的
  • IPV6 快速可达性

    我是 swift 和 xcode 的新手 并且我的应用程序因 IPV6 而被拒绝 性能 2 1 当我们执行以下操作时 您的应用程序会在运行 iOS 9 3 5 并连接到 IPv6 网络的 iPad 和 iPhone 上崩溃 具体来说 当我们

随机推荐