将 UILabel 的某些部分变成 UIButton?
Turn some parts of UILabel to act like a UIButton?
我有一个属性字符串 UILabel
,我能够为文本的某些部分着色
let text = "Why did \(event) give \(event2) a 5 stars review? Details here. "
let linkTextWithColor = "Why did"
let range = (text as NSString).rangeOfString(linkTextWithColor)
let attributedString = NSMutableAttributedString(string:text)
attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.blackColor() , range: range)
labelEvent.attributedText = attributedString
现在我想让文本的某些部分可以点击,例如 UIButton
,该怎么做?
示例 1
示例 2
我需要蓝色文本来响应触摸,以及 运行 特定功能,例如 UIButton
。
非常感谢帮助,谢谢。
假设您有一个带有文本“abc123”的 UILabel
,并且您希望“abc”起作用作为 UIButton
.
- 计算并存储包含"abc".
的矩形
- 在
UILabel
中添加一个 UITapGestureRecognizer
。
- 点击
UILabel
时,检查点击是否在矩形内。
static func getRect(str: NSAttributedString, range: NSRange, maxWidth: CGFloat) -> CGRect {
let textStorage = NSTextStorage(attributedString: str)
let textContainer = NSTextContainer(size: CGSize(width: maxWidth, height: CGFloat.max))
let layoutManager = NSLayoutManager()
layoutManager.addTextContainer(textContainer)
textStorage.addLayoutManager(layoutManager)
textContainer.lineFragmentPadding = 0
let pointer = UnsafeMutablePointer<NSRange>.alloc(1)
layoutManager.characterRangeForGlyphRange(range, actualGlyphRange: pointer)
return layoutManager.boundingRectForGlyphRange(pointer.move(), inTextContainer: textContainer)
}
let rect1 = getRect(label.attributedText!, range: NSMakeRange(0, 3), maxWidth: label.frame.width)
label.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(MyClass.tappedLabel(_:))))
func tappedLabel(sender: UITapGestureRecognizer) {
if rect1.contains(sender.locationInView(sender.view)) {
// ...
}
}
我建议你试试这个库
https://github.com/null09264/FRHyperLabel
很棒的库,易于使用,并且有几个内置示例供您试用。 Objective-c 和 Swift
中都有示例
Swift
中的示例
let str = "This is a random bit of text"
let attributes = [NSForegroundColorAttributeName: UIColor.blackColor(),
NSFontAttributeName: UIFont.systemFontOfSize(15)]
confirmLabel.attributedText = NSAttributedString(string: str, attributes: attributes)
let handler = {
(hyperLabel: FRHyperLabel!, substring: String!) -> Void in
//action here
}
//Step 3: Add link substrings
confirmLabel.setLinksForSubstrings(["random"], withLinkHandler: handler)
编辑:
如果你想去掉下划线,最好的方法是遵循 DeyaEldeen 在评论中给出的建议。
如果你去FRHyperLabel的.m文件,就去这个方法
- (void)checkInitialization {
if (!self.handlerDictionary) {
self.handlerDictionary = [NSMutableDictionary new];
}
if (!self.userInteractionEnabled) {
self.userInteractionEnabled = YES;
}
if (!self.linkAttributeDefault) {
self.linkAttributeDefault = @{NSForegroundColorAttributeName: FRHyperLabelLinkColorDefault,
NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)};
}
if (!self.linkAttributeHighlight) {
self.linkAttributeHighlight = @{NSForegroundColorAttributeName: FRHyperLabelLinkColorHighlight,
NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)};
}
}
你可以删除这个
NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)
来自属性
您想要做的是使用带有文本视图的属性字符串来制作一个 link 来充当按钮。
let attributedString = NSMutableAttributedString(string: "Some string with link", attributes: [<attributes>])
然后将它的一部分设置为 link,并使用文本视图的 linkAttributes
属性 自定义它的外观。因为这是一个按钮而不是实际的 link 我们只是为 link 放置了一个虚拟 url 以便我们稍后可以在我们的委托中处理它。
attributedString.setSubstringAsLink(substring: "link", linkURL: "CUSTOM://WHATEVER")
let linkAttributes: [String : AnyObject] = [NSForegroundColorAttributeName : .redColor(), NSUnderlineColorAttributeName : .redColor(), NSUnderlineStyleAttributeName : NSUnderlineStyle.StyleSingle.rawValue]
textView.linkTextAttributes = linkAttributes
textView.attributedText = attributedString
textView.selectable = true
textView.editable = false
textView.userInteractionEnabled = true
最后,在文本视图委托中,我们将检查方案并执行一些操作。
func textView(textView: UITextView, shouldInteractWithURL URL: NSURL, inRange characterRange: NSRange) -> Bool {
if URL.scheme == "CUSTOM" {
// Do your button actions here
}
return true
}
setSubstringAsLink 的扩展:
extension NSMutableAttributedString {
// Set part of string as URL
public func setSubstringAsLink(substring substring: String, linkURL: String) -> Bool {
let range = self.mutableString.rangeOfString(substring)
if range.location != NSNotFound {
self.addAttribute(NSLinkAttributeName, value: linkURL, range: range)
return true
}
return false
}
}
想法是使用 TTTAttributedLabel 这样的库并以这种方式使用它:
考虑以下字符串 "I want to be touchable here",其中 此处 将在触摸时执行 segue。
- 创建
TTTAttributedLabel
(UILabel
子类),将文本内容放入其中,就好像是UILabel
一样。将其委托设置为自我。然后,以这种方式将 link 添加到单词中:
Objective C
NSRange rangeWord = [attributedLabel.text rangeOfString:@"here"];
[attributedLabel addLinkToURL:[NSURL URLWithString:@"anActionOnClickHere"] withRange:rangeUser];
Swift
NSRange rangeWord = attributedLabel.text.rangeOfString("here")
attributedLabel.addLinkToURL(NSURL(string: "anActionOnClickHere"), withRange:rangeUser)
- 点击文字时,它会调用此方法,您可以在其中处理点击:
Objective C
- (void)attributedLabel:(__unused TTTAttributedLabel *)label
didSelectLinkWithURL:(NSURL *)url {
NSString *urlToString = [url absoluteString];
if ([urlToString containsString:@"anActionOnClickHere"]) { //perform segue for example
[self performSegueWithIdentifier:@"hereSegue" sender:self];
}
}
Swift
func attributedLabel(label: TTTAttributedLabel!, didSelectLinkWithURL url: NSURL!) {
NSString *urlToString = url.absoluteString()
if (urlToString.containsString("anActionOnClickHere")) { //perform segue for example
self.performSegueWithIdentifier("hereSegue",sender:self)
}
}
使用默认 link 样式,您将获得所需的蓝色。
我有一个属性字符串 UILabel
,我能够为文本的某些部分着色
let text = "Why did \(event) give \(event2) a 5 stars review? Details here. "
let linkTextWithColor = "Why did"
let range = (text as NSString).rangeOfString(linkTextWithColor)
let attributedString = NSMutableAttributedString(string:text)
attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.blackColor() , range: range)
labelEvent.attributedText = attributedString
现在我想让文本的某些部分可以点击,例如 UIButton
,该怎么做?
示例 1
示例 2
我需要蓝色文本来响应触摸,以及 运行 特定功能,例如 UIButton
。
非常感谢帮助,谢谢。
假设您有一个带有文本“abc123”的 UILabel
,并且您希望“abc”起作用作为 UIButton
.
- 计算并存储包含"abc". 的矩形
- 在
UILabel
中添加一个UITapGestureRecognizer
。 - 点击
UILabel
时,检查点击是否在矩形内。
static func getRect(str: NSAttributedString, range: NSRange, maxWidth: CGFloat) -> CGRect {
let textStorage = NSTextStorage(attributedString: str)
let textContainer = NSTextContainer(size: CGSize(width: maxWidth, height: CGFloat.max))
let layoutManager = NSLayoutManager()
layoutManager.addTextContainer(textContainer)
textStorage.addLayoutManager(layoutManager)
textContainer.lineFragmentPadding = 0
let pointer = UnsafeMutablePointer<NSRange>.alloc(1)
layoutManager.characterRangeForGlyphRange(range, actualGlyphRange: pointer)
return layoutManager.boundingRectForGlyphRange(pointer.move(), inTextContainer: textContainer)
}
let rect1 = getRect(label.attributedText!, range: NSMakeRange(0, 3), maxWidth: label.frame.width)
label.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(MyClass.tappedLabel(_:))))
func tappedLabel(sender: UITapGestureRecognizer) {
if rect1.contains(sender.locationInView(sender.view)) {
// ...
}
}
我建议你试试这个库
https://github.com/null09264/FRHyperLabel
很棒的库,易于使用,并且有几个内置示例供您试用。 Objective-c 和 Swift
中都有示例Swift
中的示例 let str = "This is a random bit of text"
let attributes = [NSForegroundColorAttributeName: UIColor.blackColor(),
NSFontAttributeName: UIFont.systemFontOfSize(15)]
confirmLabel.attributedText = NSAttributedString(string: str, attributes: attributes)
let handler = {
(hyperLabel: FRHyperLabel!, substring: String!) -> Void in
//action here
}
//Step 3: Add link substrings
confirmLabel.setLinksForSubstrings(["random"], withLinkHandler: handler)
编辑:
如果你想去掉下划线,最好的方法是遵循 DeyaEldeen 在评论中给出的建议。
如果你去FRHyperLabel的.m文件,就去这个方法
- (void)checkInitialization {
if (!self.handlerDictionary) {
self.handlerDictionary = [NSMutableDictionary new];
}
if (!self.userInteractionEnabled) {
self.userInteractionEnabled = YES;
}
if (!self.linkAttributeDefault) {
self.linkAttributeDefault = @{NSForegroundColorAttributeName: FRHyperLabelLinkColorDefault,
NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)};
}
if (!self.linkAttributeHighlight) {
self.linkAttributeHighlight = @{NSForegroundColorAttributeName: FRHyperLabelLinkColorHighlight,
NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)};
}
}
你可以删除这个
NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)
来自属性
您想要做的是使用带有文本视图的属性字符串来制作一个 link 来充当按钮。
let attributedString = NSMutableAttributedString(string: "Some string with link", attributes: [<attributes>])
然后将它的一部分设置为 link,并使用文本视图的 linkAttributes
属性 自定义它的外观。因为这是一个按钮而不是实际的 link 我们只是为 link 放置了一个虚拟 url 以便我们稍后可以在我们的委托中处理它。
attributedString.setSubstringAsLink(substring: "link", linkURL: "CUSTOM://WHATEVER")
let linkAttributes: [String : AnyObject] = [NSForegroundColorAttributeName : .redColor(), NSUnderlineColorAttributeName : .redColor(), NSUnderlineStyleAttributeName : NSUnderlineStyle.StyleSingle.rawValue]
textView.linkTextAttributes = linkAttributes
textView.attributedText = attributedString
textView.selectable = true
textView.editable = false
textView.userInteractionEnabled = true
最后,在文本视图委托中,我们将检查方案并执行一些操作。
func textView(textView: UITextView, shouldInteractWithURL URL: NSURL, inRange characterRange: NSRange) -> Bool {
if URL.scheme == "CUSTOM" {
// Do your button actions here
}
return true
}
setSubstringAsLink 的扩展:
extension NSMutableAttributedString {
// Set part of string as URL
public func setSubstringAsLink(substring substring: String, linkURL: String) -> Bool {
let range = self.mutableString.rangeOfString(substring)
if range.location != NSNotFound {
self.addAttribute(NSLinkAttributeName, value: linkURL, range: range)
return true
}
return false
}
}
想法是使用 TTTAttributedLabel 这样的库并以这种方式使用它:
考虑以下字符串 "I want to be touchable here",其中 此处 将在触摸时执行 segue。
- 创建
TTTAttributedLabel
(UILabel
子类),将文本内容放入其中,就好像是UILabel
一样。将其委托设置为自我。然后,以这种方式将 link 添加到单词中:
Objective C
NSRange rangeWord = [attributedLabel.text rangeOfString:@"here"];
[attributedLabel addLinkToURL:[NSURL URLWithString:@"anActionOnClickHere"] withRange:rangeUser];
Swift
NSRange rangeWord = attributedLabel.text.rangeOfString("here")
attributedLabel.addLinkToURL(NSURL(string: "anActionOnClickHere"), withRange:rangeUser)
- 点击文字时,它会调用此方法,您可以在其中处理点击:
Objective C
- (void)attributedLabel:(__unused TTTAttributedLabel *)label
didSelectLinkWithURL:(NSURL *)url {
NSString *urlToString = [url absoluteString];
if ([urlToString containsString:@"anActionOnClickHere"]) { //perform segue for example
[self performSegueWithIdentifier:@"hereSegue" sender:self];
}
}
Swift
func attributedLabel(label: TTTAttributedLabel!, didSelectLinkWithURL url: NSURL!) {
NSString *urlToString = url.absoluteString()
if (urlToString.containsString("anActionOnClickHere")) { //perform segue for example
self.performSegueWithIdentifier("hereSegue",sender:self)
}
}
使用默认 link 样式,您将获得所需的蓝色。