gpt4 book ai didi

ios - ios swift 的 FFLabel 库中的标签和属性颜色问题

转载 作者:行者123 更新时间:2023-11-28 09:00:57 28 4
gpt4 key购买 nike

我是 swift 的新手,在我的项目中我一直在尝试使用自定义标签,例如相关标签上的可点击“#”和“@”子字符串。我在 github 上找到了一个名为 FFLabel 的库。我已经为 FFLabel 做了一些测试。一切都很好,但我想为 '#' 和 '@' 子字符串使用不同的颜色。我试图对源代码进行一些更改。但是,它无法正常工作。此外,“#”子字符串不起作用(不可点击)。我猜源代码中存在正则表达式问题。以下是 FFLabel 的源代码:

import UIKit

@objc
public protocol FFLabelDelegate: NSObjectProtocol {
optional func labelDidSelectedLinkText(label: FFLabel, text: String)
}

public class FFLabel: UILabel {

public var linkTextColor = UIColor(red: 0, green: 63.0/255.0, blue: 121.0/255.0, alpha: 1.0)
public weak var labelDelegate: FFLabelDelegate?

// MARK: - override properties
override public var text: String? {
didSet {
updateTextStorage()
}
}

override public var attributedText: NSAttributedString? {
didSet {
updateTextStorage()
}
}

override public var font: UIFont! {
didSet {
updateTextStorage()
}
}

override public var textColor: UIColor! {
didSet {
updateTextStorage()
}
}

// MARK: - upadte text storage and redraw text
private func updateTextStorage() {
if attributedText == nil {
return
}

let attrStringM = addLineBreak(attributedText!)
regexLinkRanges(attrStringM)
addLinkAttribute(attrStringM)

textStorage.setAttributedString(attrStringM)

setNeedsDisplay()
}

/// add link attribute
private func addLinkAttribute(attrStringM: NSMutableAttributedString) {
var range = NSRange(location: 0, length: 0)
var attributes = attrStringM.attributesAtIndex(0, effectiveRange: &range)

attributes[NSFontAttributeName] = font!
attributes[NSForegroundColorAttributeName] = textColor
attrStringM.addAttributes(attributes, range: range)

attributes[NSForegroundColorAttributeName] = linkTextColor

for r in linkRanges {
attrStringM.setAttributes(attributes, range: r)
}
}

/// use regex check all link ranges
private let patterns = ["[a-zA-Z]*://[a-zA-Z0-9/\\.]*", "#.*?#", "@[\\u4e00-\\u9fa5a-zA-Z0-9_-]*"]
private func regexLinkRanges(attrString: NSAttributedString) {
linkRanges.removeAll()
let regexRange = NSRange(location: 0, length: count(attrString.string))

for pattern in patterns {
let regex = NSRegularExpression(pattern: pattern, options: NSRegularExpressionOptions.DotMatchesLineSeparators, error: nil)
let results = regex?.matchesInString(attrString.string, options: NSMatchingOptions(rawValue: 0), range: regexRange)

if let results = results {
for r in results {
linkRanges.append(r.rangeAtIndex(0))
}
}
}
}

/// add line break mode
private func addLineBreak(attrString: NSAttributedString) -> NSMutableAttributedString {
let attrStringM = NSMutableAttributedString(attributedString: attrString)

var range = NSRange(location: 0, length: 0)
var attributes = attrStringM.attributesAtIndex(0, effectiveRange: &range)
var paragraphStyle = attributes[NSParagraphStyleAttributeName] as? NSMutableParagraphStyle

if paragraphStyle != nil {
paragraphStyle!.lineBreakMode = NSLineBreakMode.ByWordWrapping
} else {
// iOS 8.0 can not get the paragraphStyle directly
paragraphStyle = NSMutableParagraphStyle()
paragraphStyle!.lineBreakMode = NSLineBreakMode.ByWordWrapping
attributes[NSParagraphStyleAttributeName] = paragraphStyle

attrStringM.setAttributes(attributes, range: range)
}

return attrStringM
}

public override func drawTextInRect(rect: CGRect) {
let range = glyphsRange()
let offset = glyphsOffset(range)

layoutManager.drawBackgroundForGlyphRange(range, atPoint: offset)
layoutManager.drawGlyphsForGlyphRange(range, atPoint: CGPointZero)
}

private func glyphsRange() -> NSRange {
return NSRange(location: 0, length: textStorage.length)
}

private func glyphsOffset(range: NSRange) -> CGPoint {
let rect = layoutManager.boundingRectForGlyphRange(range, inTextContainer: textContainer)
let height = (bounds.height - rect.height) * 0.5

return CGPoint(x: 0, y: height)
}

// MARK: - touch events

public override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
let location = (touches.first as! UITouch).locationInView(self)

selectedRange = linkRangeAtLocation(location)
modifySelectedAttribute(true)
}

public override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
let location = (touches.first as! UITouch).locationInView(self)

if let range = linkRangeAtLocation(location) {
if !(range.location == selectedRange?.location && range.length == selectedRange?.length) {
modifySelectedAttribute(false)
selectedRange = range
modifySelectedAttribute(true)
}
} else {
modifySelectedAttribute(false)
}
}


public override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
if selectedRange != nil {
let text = (textStorage.string as NSString).substringWithRange(selectedRange!)
labelDelegate?.labelDidSelectedLinkText!(self, text: text)

let when = dispatch_time(DISPATCH_TIME_NOW, Int64(0.25 * Double(NSEC_PER_SEC)))
dispatch_after(when, dispatch_get_main_queue()) {
self.modifySelectedAttribute(false)
}
}
}

public override func touchesCancelled(touches: Set<NSObject>!, withEvent event: UIEvent!) {
modifySelectedAttribute(false)

}

private func modifySelectedAttribute(isSet: Bool) {
if selectedRange == nil {
return
}

var attributes = textStorage.attributesAtIndex(0, effectiveRange: nil)
attributes[NSForegroundColorAttributeName] = linkTextColor
let range = selectedRange!

textStorage.addAttributes(attributes, range: range)

setNeedsDisplay()
}

private func linkRangeAtLocation(location: CGPoint) -> NSRange? {
if textStorage.length == 0 {
return nil
}

let offset = glyphsOffset(glyphsRange())
let point = CGPoint(x: offset.x + location.x, y: offset.y + location.y)
let index = layoutManager.glyphIndexForPoint(point, inTextContainer: textContainer)

for r in linkRanges {
if index >= r.location && index <= r.location + r.length {
return r
}
}

return nil
}

// MARK: - init functions
override public init(frame: CGRect) {
super.init(frame: frame)

prepareLabel()
}

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

prepareLabel()
}

public override func layoutSubviews() {
super.layoutSubviews()

textContainer.size = bounds.size
}

private func prepareLabel() {
textStorage.addLayoutManager(layoutManager)
layoutManager.addTextContainer(textContainer)

textContainer.lineFragmentPadding = 0

userInteractionEnabled = true
}

// MARK: lazy properties
private lazy var linkRanges = [NSRange]()
private var selectedRange: NSRange?
private lazy var textStorage = NSTextStorage()
private lazy var layoutManager = NSLayoutManager()
private lazy var textContainer = NSTextContainer()
}

谢谢你的回答

国王问好

注意:我通过将主题标签表达式更改为 #[\\u4e00-\\u9fa5a-zA-Z0-9_-]*< 解决了主题标签可点击问题(正则表达式问题)/。但其余问题仍在继续。

最佳答案

你也可以试试 ActiveLabel.swift 这是 UILabel 的替代品,支持用 Swift 编写的标签 (#)、提及 (@) 和 URL (http://)。 p>

也许这正是您要寻找的。给用户名、主题标签和链接不同的颜色就这么简单:

label.textColor = .blackColor()
label.hashtagColor = .blueColor()
label.mentionColor = .greenColor()
label.URLColor = .redColor()

免责声明:我是图书馆的作者。

关于ios - ios swift 的 FFLabel 库中的标签和属性颜色问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32033362/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com