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

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 = []

// 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?

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值