How to make URL/Phone-clickable UILabel?

I want to create a clickable label on my app leading me to a Safari webpage. I also want the user to be able to phone the numbers only by clicking on them ?

Thanks for your advices

112079 次浏览

您可以使用 UITextView并选择检查器中的链接、电话号码和其他东西的检测。

您可以创建自定义 UIButton 和 setText,并使用它们添加一个方法。

UIButton *sampleButton = [UIButton buttonWithType:UIButtonTypeCustom];
[sampleButton setFrame:CGRectMake(kLeftMargin, 10, self.view.bounds.size.width - kLeftMargin - kRightMargin, 52)];
[sampleButton setTitle:@"URL Text" forState:UIControlStateNormal];
[sampleButton setFont:[UIFont boldSystemFontOfSize:20]];




[sampleButton addTarget:self action:@selector(buttonPressed) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:sampleButton];




-(void)buttonPressed:(id)sender{
// open url
}

Https://github.com/mattt/tttattributedlabel

这绝对是你需要的。还可以为标签应用属性(如下划线) ,并对其应用不同的颜色。只要检查可点击的网址说明。

主要是做以下事情:

NSRange range = [label.text rangeOfString:@"me"];
[label addLinkToURL:[NSURL URLWithString:@"http://github.com/mattt/"] withRange:range]; // Embedding a custom link in a substring

使用 UITextView代替 UILabel,它有一个属性可以将文本转换为超链接。

目标 C:

yourTextView.editable = NO;
yourTextView.dataDetectorTypes = UIDataDetectorTypeAll;

斯威夫特:

yourTextView.editable = false;
yourTextView.dataDetectorTypes = UIDataDetectorTypes.All;

这将自动检测链接。

详情请参阅 文件

使用这个我喜欢它这么多,因为创建蓝色链接到特定的文本,而不是整个标签文本: FRHyperLabel

Smartly applying hyperlink on Terms of Use

要做的:

  1. 从上面的链接下载并将 FRHyperLabel.hFRHyperLabel.m复制到您的项目。

  2. Storyboard中拖放 UILabel,并在标识检查器中将自定义类名定义为 FRHyperLabel,如图所示。

enter image description here

  1. 将 UILabel 从故事板连接到 viewController.h 文件

@property (weak, nonatomic) IBOutlet FRHyperLabel *label;

  1. 现在在 viewController.m 文件中添加以下代码。

`NSString *string = @"By uploading I agree to the Terms of Use"; NSDictionary * properties =@{ NSFontAttributeName: [ UIFont preredFontForTextStyle: UIFontTextStyleHeadline ]} ;

_label.attributedText = [[NSAttributedString alloc]initWithString:string attributes:attributes];
[_label setFont:[_label.font fontWithSize:13.0]];


[_label setLinkForSubstring:@"Terms of Use" withLinkHandler:^(FRHyperLabel *label, NSString *substring){
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://www.google.com"]];
}];`
  1. 运行它。

使用 UITextView 代替 UILabel,它具有将文本转换为超链接的属性

快速代码:

yourTextView.editable = false
yourTextView.dataDetectorTypes = UIDataDetectorTypes.All
//or
yourTextView.dataDetectorTypes = UIDataDetectorTypes.PhoneNumber
//or
yourTextView.dataDetectorTypes = UIDataDetectorTypes.Link

如果你想让 UILabel 而不是 UITextView 来处理这个问题,你可以让 UILabel 子类,就像这个:

class LinkedLabel: UILabel {


fileprivate let layoutManager = NSLayoutManager()
fileprivate let textContainer = NSTextContainer(size: CGSize.zero)
fileprivate var textStorage: NSTextStorage?




override init(frame aRect:CGRect){
super.init(frame: aRect)
self.initialize()
}


required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.initialize()
}


func initialize(){


let tap = UITapGestureRecognizer(target: self, action: #selector(LinkedLabel.handleTapOnLabel))
self.isUserInteractionEnabled = true
self.addGestureRecognizer(tap)
}


override var attributedText: NSAttributedString?{
didSet{
if let _attributedText = attributedText{
self.textStorage = NSTextStorage(attributedString: _attributedText)


self.layoutManager.addTextContainer(self.textContainer)
self.textStorage?.addLayoutManager(self.layoutManager)


self.textContainer.lineFragmentPadding = 0.0;
self.textContainer.lineBreakMode = self.lineBreakMode;
self.textContainer.maximumNumberOfLines = self.numberOfLines;
}


}
}


func handleTapOnLabel(tapGesture:UITapGestureRecognizer){


let locationOfTouchInLabel = tapGesture.location(in: tapGesture.view)
let labelSize = tapGesture.view?.bounds.size
let textBoundingBox = self.layoutManager.usedRect(for: self.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 = self.layoutManager.characterIndex(for: locationOfTouchInTextContainer, in: self.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)




self.attributedText?.enumerateAttribute(NSLinkAttributeName, in: NSMakeRange(0, (self.attributedText?.length)!), options: NSAttributedString.EnumerationOptions(rawValue: UInt(0)), using:{
(attrs: Any?, range: NSRange, stop: UnsafeMutablePointer<ObjCBool>) in


if NSLocationInRange(indexOfCharacter, range){
if let _attrs = attrs{


UIApplication.shared.openURL(URL(string: _attrs as! String)!)
}
}
})


}}

此类是通过重用此 回答中的代码创建的。要创建属性化字符串,请查看这个 回答。和 给你你可以找到如何使电话网址。

extension UITapGestureRecognizer {


func didTapAttributedTextInLabel(label: UILabel, inRange targetRange: NSRange) -> Bool {


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
textContainer.size = label.bounds.size


// main code
let locationOfTouchInLabel = self.location(in: label)


let indexOfCharacter = layoutManager.characterIndex(for: locationOfTouchInLabel, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
let indexOfCharacterRange = NSRange(location: indexOfCharacter, length: 1)
let indexOfCharacterRect = layoutManager.boundingRect(forGlyphRange: indexOfCharacterRange, in: textContainer)
let deltaOffsetCharacter = indexOfCharacterRect.origin.x + indexOfCharacterRect.size.width


if locationOfTouchInLabel.x > deltaOffsetCharacter {
return false
} else {
return NSLocationInRange(indexOfCharacter, targetRange)
}
}
}

使用 UIButton 的 Swift 4.0可能解决方案

     phoneButton = UIButton(frame: CGRect(x: view.frame.width * 0, y: view.frame.height * 0.1, width: view.frame.width * 1, height: view.frame.height * 0.05))
phoneButton.setTitle("333-333-3333", for: .normal )
phoneButton.setTitleColor(UIColor(red: 0 / 255, green: 0 / 255, blue: 238 / 255, alpha: 1.0), for: .normal)
phoneButton.addTarget(self, action: #selector(self.callPhone), for: .touchUpInside )


@objc func callPhone(){


UIApplication.shared.open(URL(string:"tel://3333333333")!, options: [:] , completionHandler: nil)




}

Why not just use NSMutableAttributedString?

let attributedString = NSMutableAttributedString(string: "Want to learn iOS? Just visit developer.apple.com!")
attributedString.addAttribute(.link, value: "https://developer.apple.com", range: NSRange(location: 30, length: 50))


myView.attributedText = attributedString

你可以找到更多的细节 给你