段落中部分文案添加点击事件

import UIKit
import CoreMedia
import CoreMIDI

open class HHTouchableLabel: UILabel
{
    var touchBlocks:[String:()->Void] = [:]

    public required init?(coder aDecoder: NSCoder)
    {
        super.init(coder: aDecoder)
        initView()
    }

    public required override init(frame: CGRect) {
        super.init(frame: frame)
        initView()
    }

    func initView()
    {
        isUserInteractionEnabled = true
        let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(didTap))
        tapRecognizer.numberOfTapsRequired = 1
        tapRecognizer.numberOfTouchesRequired = 1
        addGestureRecognizer(tapRecognizer)
    }

    @objc func didTap(_ gesture: UITapGestureRecognizer)
    {
        guard let attrText = attributedText else
        {
            return
        }

        let layoutManager = NSLayoutManager()
        let textContainer = NSTextContainer(size: frame.size)

        textContainer.lineBreakMode = lineBreakMode
        textContainer.maximumNumberOfLines = self.numberOfLines
        textContainer.lineFragmentPadding = 0
        layoutManager.addTextContainer(textContainer)

        let textStorage = NSTextStorage(attributedString: attrText)
        textStorage.addLayoutManager(layoutManager)
        let labelText = attrText.string

        for item in touchBlocks {
            let key = item.0
            let block = item.1
            var ranges:[Range<String.Index>] = []
            while let range = labelText.range(of: key, options: .caseInsensitive, range: (ranges.last?.upperBound ?? labelText.startIndex)..<labelText.endIndex, locale: nil) {
                ranges.append(range)
                let startPos = labelText.distance(from: labelText.startIndex, to: range.lowerBound)
                let endPos = labelText.distance(from: labelText.startIndex, to: range.upperBound)
                let newRange = NSRange(location: startPos, length: endPos - startPos)
                let glyphRange:NSRangePointer = NSRangePointer.allocate(capacity:MemoryLayout<NSRange>.size)
                layoutManager.characterRange(forGlyphRange: newRange, actualGlyphRange: glyphRange)
                let glypRect = layoutManager.boundingRect(forGlyphRange: glyphRange.move(), in: textContainer)
                glyphRange.deinitialize(count:MemoryLayout<NSRange>.size)
                let touchPoint = gesture.location(ofTouch: 0, in: self)
                if glypRect.contains(touchPoint){
                    block()
                }
            }
        }

    }

    open func addEventCallback(_ string:String,block:@escaping ()->Void)
    {
        touchBlocks[string] = block
    }
}

0 0 投票数
文章评分
订阅评论
提醒
guest
0 评论
内联反馈
查看所有评论
京ICP备17066706号-1
0
希望看到您的想法,请您发表评论x