如何在 ios 中创建可点击的标签 Like Facebook?
How to create clickable label Like Facebook in ios?
我正在开发一款社交应用,我需要在其中展示 post 和分享等。
我还需要显示标签朋友。
当 post 显示在列表中时 UI 也类似于 Facebook post。请检查下面的屏幕截图。
如您所见,单击 Post 标题是单行属性,当用户单击他的姓名 Person Name Abc 时,我需要在其中打开用户配置文件并希望在用户点击 Buzzfeed india、
时打开页面
因为我们需要使用 UI 标签来显示这样的内容,所以我无法点击特定的词。我已经尝试过 https://github.com/null09264/FRHyperLabel 但是当有多行时然后点击单词并不完美。
您可以使用 TTTAttributedLabel 使 UILabel 中的特定部分或单词可点击。
例如
label.text = @"Fork me on GitHub!"; // Repository URL will be automatically detected and linked
NSRange range = [label.text rangeOfString:@"me"];
[label addLinkToURL:[NSURL URLWithString:@"meUrl"] withRange:range];
在这里,我变成可点击的,在点击该词时,委托方法 didSelectLinkWithURL 被调用,您可以在该函数中检查 link
(void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithURL:(NSURL *)url {
NSLog(@"link %@", [url absoluteString]);
if ([url absoluteString] == @"meUrl") {
//implement your logic here
}
NSLog(@"whole label %@", label);
}
试试这个:
添加扩展程序
extension UITapGestureRecognizer {
func didTapAttributedTextInLabel(label: UILabel, inRange targetRange: NSRange) -> Bool {
// Create instances of NSLayoutManager, NSTextContainer and NSTextStorage
let layoutManager = NSLayoutManager()
let textContainer = NSTextContainer(size: CGSize.zero)
let textStorage = NSTextStorage(attributedString: label.attributedText!)
// Configure layoutManager and textStorage
layoutManager.addTextContainer(textContainer)
textStorage.addLayoutManager(layoutManager)
// Configure textContainer
textContainer.lineFragmentPadding = 0.0
textContainer.lineBreakMode = label.lineBreakMode
textContainer.maximumNumberOfLines = label.numberOfLines
let labelSize = label.bounds.size
textContainer.size = labelSize
// Find the tapped character location and compare it to the specified range
let locationOfTouchInLabel = self.location(in: label)
let textBoundingBox = layoutManager.usedRect(for: textContainer)
let textContainerOffset = CGPoint(x:(labelSize.width - textBoundingBox.size.width) * 0.5 - textBoundingBox.origin.x,y:(labelSize.height - textBoundingBox.size.height) * 0.5 - textBoundingBox.origin.y);
let locationOfTouchInTextContainer = CGPoint(x:locationOfTouchInLabel.x - textContainerOffset.x,y:locationOfTouchInLabel.y - textContainerOffset.y);
let indexOfCharacter = layoutManager.characterIndex(for: locationOfTouchInTextContainer, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
return NSLocationInRange(indexOfCharacter, targetRange)
}
}
Then Add UITapGestureRecognizer
on your UILable. Please make sure UILabel.isUserInteractionEnabled
is true
override func viewDidLoad() {
super.viewDidLoad()
initialSetup()
}
func initialSetup(){
let tap = UITapGestureRecognizer(target: self, action: #selector(self.didTap(_:)))
lblTitle.addGestureRecognizer(tap)
lblTitle.isUserInteractionEnabled = true
lblTitle.numberOfLines = 0
let personname = "Person Name Abc"
let buzzIndia = "Buzzfeed india"
let str = "\(personname) shared \(buzzIndia)'s video"
let attributedString = NSMutableAttributedString(string:str)
let range = (str as NSString).range(of: personname)
attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.black, range: range)
if let font = UIFont(name: "Helvetica Bold", size: 14) {
attributedString.addAttribute(NSFontAttributeName, value: font, range: range)
}
let rangeBuzz = (str as NSString).range(of: buzzIndia)
attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.black, range: rangeBuzz)
if let font = UIFont(name: "Helvetica Bold", size: 14) {
attributedString.addAttribute(NSFontAttributeName, value: font, range: rangeBuzz)
}
lblTitle.attributedText = attributedString
}
func didTap(_ gesture: UITapGestureRecognizer) {
let text = (lblTitle.text)!
let name = (text as NSString).range(of: "Person Name Abc")
let buzzfeed = (text as NSString).range(of: "Buzzfeed india")
if gesture.didTapAttributedTextInLabel(label: lblTitle, inRange: name) {
//Repective "Person Name Abc" action
print("Person Name Abc")
}else if gesture.didTapAttributedTextInLabel(label: lblTitle, inRange: buzzfeed) {
//Repective "Buzzfeed india" action
print("Buzzfeed india")
}else {
print("other tapped")
}
}
参考:http://samwize.com/2016/03/04/how-to-create-multiple-tappable-links-in-a-uilabel/
我正在开发一款社交应用,我需要在其中展示 post 和分享等。 我还需要显示标签朋友。
当 post 显示在列表中时 UI 也类似于 Facebook post。请检查下面的屏幕截图。
如您所见,单击 Post 标题是单行属性,当用户单击他的姓名 Person Name Abc 时,我需要在其中打开用户配置文件并希望在用户点击 Buzzfeed india、
时打开页面因为我们需要使用 UI 标签来显示这样的内容,所以我无法点击特定的词。我已经尝试过 https://github.com/null09264/FRHyperLabel 但是当有多行时然后点击单词并不完美。
您可以使用 TTTAttributedLabel 使 UILabel 中的特定部分或单词可点击。
例如
label.text = @"Fork me on GitHub!"; // Repository URL will be automatically detected and linked
NSRange range = [label.text rangeOfString:@"me"];
[label addLinkToURL:[NSURL URLWithString:@"meUrl"] withRange:range];
在这里,我变成可点击的,在点击该词时,委托方法 didSelectLinkWithURL 被调用,您可以在该函数中检查 link
(void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithURL:(NSURL *)url {
NSLog(@"link %@", [url absoluteString]);
if ([url absoluteString] == @"meUrl") {
//implement your logic here
}
NSLog(@"whole label %@", label);
}
试试这个:
添加扩展程序
extension UITapGestureRecognizer {
func didTapAttributedTextInLabel(label: UILabel, inRange targetRange: NSRange) -> Bool {
// Create instances of NSLayoutManager, NSTextContainer and NSTextStorage
let layoutManager = NSLayoutManager()
let textContainer = NSTextContainer(size: CGSize.zero)
let textStorage = NSTextStorage(attributedString: label.attributedText!)
// Configure layoutManager and textStorage
layoutManager.addTextContainer(textContainer)
textStorage.addLayoutManager(layoutManager)
// Configure textContainer
textContainer.lineFragmentPadding = 0.0
textContainer.lineBreakMode = label.lineBreakMode
textContainer.maximumNumberOfLines = label.numberOfLines
let labelSize = label.bounds.size
textContainer.size = labelSize
// Find the tapped character location and compare it to the specified range
let locationOfTouchInLabel = self.location(in: label)
let textBoundingBox = layoutManager.usedRect(for: textContainer)
let textContainerOffset = CGPoint(x:(labelSize.width - textBoundingBox.size.width) * 0.5 - textBoundingBox.origin.x,y:(labelSize.height - textBoundingBox.size.height) * 0.5 - textBoundingBox.origin.y);
let locationOfTouchInTextContainer = CGPoint(x:locationOfTouchInLabel.x - textContainerOffset.x,y:locationOfTouchInLabel.y - textContainerOffset.y);
let indexOfCharacter = layoutManager.characterIndex(for: locationOfTouchInTextContainer, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
return NSLocationInRange(indexOfCharacter, targetRange)
}
}
Then Add
UITapGestureRecognizer
on your UILable. Please make sureUILabel.isUserInteractionEnabled
is true
override func viewDidLoad() {
super.viewDidLoad()
initialSetup()
}
func initialSetup(){
let tap = UITapGestureRecognizer(target: self, action: #selector(self.didTap(_:)))
lblTitle.addGestureRecognizer(tap)
lblTitle.isUserInteractionEnabled = true
lblTitle.numberOfLines = 0
let personname = "Person Name Abc"
let buzzIndia = "Buzzfeed india"
let str = "\(personname) shared \(buzzIndia)'s video"
let attributedString = NSMutableAttributedString(string:str)
let range = (str as NSString).range(of: personname)
attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.black, range: range)
if let font = UIFont(name: "Helvetica Bold", size: 14) {
attributedString.addAttribute(NSFontAttributeName, value: font, range: range)
}
let rangeBuzz = (str as NSString).range(of: buzzIndia)
attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.black, range: rangeBuzz)
if let font = UIFont(name: "Helvetica Bold", size: 14) {
attributedString.addAttribute(NSFontAttributeName, value: font, range: rangeBuzz)
}
lblTitle.attributedText = attributedString
}
func didTap(_ gesture: UITapGestureRecognizer) {
let text = (lblTitle.text)!
let name = (text as NSString).range(of: "Person Name Abc")
let buzzfeed = (text as NSString).range(of: "Buzzfeed india")
if gesture.didTapAttributedTextInLabel(label: lblTitle, inRange: name) {
//Repective "Person Name Abc" action
print("Person Name Abc")
}else if gesture.didTapAttributedTextInLabel(label: lblTitle, inRange: buzzfeed) {
//Repective "Buzzfeed india" action
print("Buzzfeed india")
}else {
print("other tapped")
}
}
参考:http://samwize.com/2016/03/04/how-to-create-multiple-tappable-links-in-a-uilabel/