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 评论