119

我想在我的应用程序上创建一个可点击的标签,引导我进入 Safari 网页。我还希望用户只能通过单击来拨打电话号码?

感谢您的建议

4

10 回答 10

141

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

于 2012-05-21T08:43:40.243 回答
98

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

目标-C:

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

迅速:

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

这将自动检测链接。

有关详细信息,请参阅文档

于 2012-05-21T18:46:03.697 回答
29

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
于 2012-05-21T08:53:05.310 回答
12

您可以根据需要制作自定义 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
}
于 2012-05-21T08:44:10.420 回答
11

如果您希望这由 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)!)
            }
        }
    })

}}

此类是通过重用此答案中的代码制成的。为了使属性字符串检查这个答案在这里您可以找到如何制作电话网址。

于 2016-11-22T16:35:23.540 回答
7

使用这个我非常喜欢它,因为它只在整个标签文本上创建了与特定文本的蓝色链接:FRHyperLabel

在使用条款上巧妙地应用超链接

去做:

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

  2. 拖放UILabel您的Storyboard并定义自定义类名称以FRHyperLabel识别检查器,如图所示。

在此处输入图像描述

  1. 将您的 UILabel 从情节提要连接到您的 viewController.h 文件

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

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

`NSString *string = @"上传即表示同意使用条款"; NSDictionary *attributes = @{NSFontAttributeName: [UIFont preferredFontForTextStyle: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. 并运行它。
于 2016-03-04T12:11:09.797 回答
5

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

SWIFT代码:

yourTextView.editable = false
yourTextView.dataDetectorTypes = UIDataDetectorTypes.All
//or
yourTextView.dataDetectorTypes = UIDataDetectorTypes.PhoneNumber
//or
yourTextView.dataDetectorTypes = UIDataDetectorTypes.Link
于 2016-07-04T16:54:33.847 回答
0
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)
        }
    }
}
于 2017-05-31T11:56:47.927 回答
0

为什么不直接使用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

您可以在此处找到更多详细信息

于 2019-09-03T19:31:48.783 回答
-3

使用 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)


    }
于 2018-03-01T16:59:29.243 回答