UILabel显示HTML富文本,响应点击事件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UILabel显示HTML富文本,响应点击事件相关的知识,希望对你有一定的参考价值。

参考技术A importFoundation

protocol htmlLabelDelegate

    funcclickUrl(url:NSURL)

    funcclickImage(image:UIImage)



class HtmlLabel: UILabel

    //Mark --`TextKit` 的核心对象 绘制`textStorage`的文本内容

    /// 属性文本存储

    private lazy var textStorage = NSTextStorage()

    /// 负责文本`字形`布局 1.绘制背景  2.绘制Glyphs 字形 3.获取点中字符的索引

    private lazy var layoutManager = NSLayoutManager()

    /// 设定文本绘制的范围

    private lazy var textContainer = NSTextContainer()

    var delegate:HtmlLabelDelegate?

    var attachments:Array<AttachmentModel> = []

    // Mark: 一旦内容变化 需要让 textStorge 响应变化

    // Mark: --重写属性

    override var text: String?

        didSet

            // 重新准备文本内容

            prepareTextSystem()

       

   

    override var attributedText: NSAttributedString?

        didSet

            // 重新准备文本内容

            prepareTextSystem()

       

   

    // Mark: -- 构造函数

    overrideinit(frame:CGRect)

        super.init(frame: frame)

      prepareTextSystem()

   

    requiredinit?(coder aDecoder:NSCoder)

      super.init(coder: aDecoder)

      prepareTextSystem()

   

    // Mark: --交互

    overridefunctouchesBegan(_touches:Set, with event:UIEvent?)

        guard let location = touches.first?.location(in:self)else

           return

       

        for r in attachments

            if(r.rect?.contains(location))!

                ifr.image!=nil

                    print("click image")

                    break

                else if r.url!=nil

                    print("click url")

                    break

               

            else

                print("没戳着")

           

       

   

    override func drawText(in rect:CGRect)

        letrange =NSRange(location:0, length:textStorage.length)

        ///绘制背景

        layoutManager.drawBackground(forGlyphRange: range, at:CGPoint())

        /// 绘制Glyphs 字形

        /// CGPoint():从原点绘制

        layoutManager.drawGlyphs(forGlyphRange: range, at:CGPoint())

   

    override func layoutSubviews()

        super.layoutSubviews()

        //指定绘制文本的区域

        textContainer.size = bounds.size

   



private extension HtmlLabel

    ///准备文本系统

    func prepareTextSystem()

        // 0.开启交互

        isUserInteractionEnabled = true

        //1.准备文本内容

        prepareTextContent()

        //2.设置对象的关系

        textStorage.addLayoutManager(layoutManager)

        layoutManager.addTextContainer(textContainer)

   

    /// 使用`textStorage`接管label内容

    func prepareTextContent()

        ifletattributedText =attributedText

            textStorage.setAttributedString(attributedText)

        elseiflettext =text

            textStorage.setAttributedString(NSAttributedString(string: text))

        else

            textStorage.setAttributedString(NSAttributedString(string: ""))

       

        getAttachments()

   

    func getAttachments()

        if attributedText == nil

            return

       

        attributedText!.enumerateAttributes(in: NSRange(location: 0, length: attributedText!.length), options: NSAttributedString.EnumerationOptions.longestEffectiveRangeNotRequired, using: (dic, range, stop) in

                    if dic.keys.contains(NSAttributedString.Key.attachment)

                        let attacment:NSTextAttachment = dic[NSAttributedString.Key.attachment] as! NSTextAttachment

                        ifattacment.fileWrapper!=nil&&attacment.fileWrapper!.regularFileContents!=nil

                            letrect =boundingRectForCharacterRange(range: range)

                            letattachmentModel =AttachmentModel()

                            attachmentModel.image=UIImage(data: attacment.fileWrapper!.regularFileContents!)

                            attachmentModel.rect= rect

                            attachments.append(attachmentModel)

                       

                    else if dic.keys.contains(NSAttributedString.Key.link)

                        leturl:NSURL= dic[NSAttributedString.Key.link]as!NSURL

                        letrect =boundingRectForCharacterRange(range: range)

                        letattachmentModel =AttachmentModel()

                        attachmentModel.url= url

                        attachmentModel.rect= rect

                        attachments.append(attachmentModel)

                   

                )

    

    private func boundingRectForCharacterRange(range:NSRange) ->CGRect

        textContainer.lineFragmentPadding = 0

        letglyphRange =layoutManager.characterRange(forGlyphRange: range, actualGlyphRange:nil)

        letrect =layoutManager.boundingRect(forGlyphRange: glyphRange, in:textContainer)

        returnrect

   



class AttachmentModel

    varimage:UIImage?

    varurl:NSURL?

    varrect:CGRect?

具有富文本 HTML 功能和自动布局支持的 UILabel

【中文标题】具有富文本 HTML 功能和自动布局支持的 UILabel【英文标题】:UILabel with Rich Text HTML capability and Auto Layout support 【发布时间】:2013-06-24 11:19:23 【问题描述】:

我正在寻找一种在 UILabel 中显示样式文本的方法。有多种管理方法:

使用 UIWebView OHAttributedLabel RTLabel DTCoreText

然而,这些可能性似乎不像 UILabel 那样支持自动布局:

如果我使用视觉格式 V:|[styledLabel]H:|[styledLabel] 的约束(未设置绝对高度或宽度),则不会显示标签子类(例如 RTLabel)。如果设置了高度和宽度,一切正常。

有没有办法使用上面的约束来管理样式文本?

提前致谢

【问题讨论】:

你有什么解决办法吗?? 【参考方案1】:

我在使用 OHAttributedLabel 和自动布局时遇到了标签未显示的相同问题。我刚刚尝试了 TTTAttributedLabel (https://github.com/mattt/TTTAttributedLabel),它似乎有效。必须进行更多测试以确保一切正常……如果您也想检查一下(并且仍然需要这个),请提个醒:)

【讨论】:

【参考方案2】:

使用属性字符串和 UILabel,这在 Autolayout 使用的同时成为可能 (iOS6)。如果您需要将 HTML 转换为属性字符串,请尝试this。

【讨论】:

以上是关于UILabel显示HTML富文本,响应点击事件的主要内容,如果未能解决你的问题,请参考以下文章

iOS富文本Label实现点击事件,类似Word在横线上输入编辑

富文本鼠标离开textarea事件

Android中富文本用法包括点击事件处理

Android中富文本用法包括点击事件处理

具有富文本 HTML 功能和自动布局支持的 UILabel

Android中Textview加载HTML方法——RichText富文本解析器