Как сделать UILabel URL/телефона кликабельным?

Я хочу создать интерактивную метку в своем приложении, ведущую меня на веб-страницу Safari. Я также хочу, чтобы пользователь мог звонить по номерам, только нажимая на них?

Спасибо за ваши советы


person Rob    schedule 21.05.2012    source источник
comment
Возможный дубликат Создайте ссылки с возможностью нажатия в NSAttributedText из UILabel?   -  person nalexn    schedule 13.02.2017


Ответы (9)


Вы можете использовать UITextView и выбрать Обнаружение ссылок, телефонных номеров и других вещей в инспекторе.

person Basel    schedule 21.05.2012
comment
У меня есть метка с автоматическим изменением размера, которая может вместить N строк текста. Как я могу сделать ссылки в этой метке кликабельными без реализации UITextView. - person bibscy; 30.10.2018
comment
@bibscy, тогда вы можете использовать NSAttributedText. Посмотрите на stackoverflow.com/questions/1256887/ - person Basel; 31.10.2018

Используйте UITextView вместо UILabel, и у него есть свойство преобразовывать ваш текст в гиперссылку.

Цель-C:

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

Быстрый:

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

Это автоматически обнаружит ссылки.

Подробнее см. в документации.

person Sameera Chathuranga    schedule 21.05.2012
comment
это окрашивает ссылку в синий цвет и подчеркивает ее, но, кажется, делает ее кликабельной, по крайней мере, на iOS 7. - person Ben H; 29.04.2014
comment
Код Swift: yourTextView.editable = false; yourTextView.dataDetectorTypes = UIDataDetectorTypes.All; - person Thiago Arreguy; 04.07.2016
comment
вопрос касается UILabel, а не UITextView. - person swift2geek; 31.07.2018

https://github.com/mattt/TTTAttributedLabel

Это определенно то, что вам нужно. Вы также можете применять атрибуты для своей метки, такие как подчеркивание, и применять к ней разные цвета. Просто проверьте инструкции для интерактивных URL-адресов.

В основном вы делаете что-то вроде следующего:

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

Вы можете создать собственный 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
}
person Rohit Dhawan    schedule 21.05.2012
comment
Установка шрифта теперь выполняется: button.titleLabel.font = [UIFont systemFontOfSize:size]; - person Leon; 16.04.2018

Если вы хотите, чтобы это обрабатывалось 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)!)
            }
        }
    })

}}

Этот класс был создан путем повторного использования кода из этого ответа. Чтобы создать строки с атрибутами, ознакомьтесь с этим ответом. И здесь вы можете найти, как сделать URL-адреса телефонов.

person Bojan Bozovic    schedule 22.11.2016

Используйте это, мне так понравилось, так как создает ссылку с синим цветом только на определенный текст, а не на весь текст метки: FRHyperLabel

«Разумное

To do:

  1. Скачайте по ссылке выше и скопируйте FRHyperLabel.h, FRHyperLabel.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. И запустить его.
person karan    schedule 04.03.2016

Используйте UITextView вместо UILabel, и у него есть свойство преобразовывать ваш текст в гиперссылку.

Свифт-код:

yourTextView.editable = false
yourTextView.dataDetectorTypes = UIDataDetectorTypes.All
//or
yourTextView.dataDetectorTypes = UIDataDetectorTypes.PhoneNumber
//or
yourTextView.dataDetectorTypes = UIDataDetectorTypes.Link
person Thiago Arreguy    schedule 04.07.2016
comment
вопрос как использовать в UILabel, а не в TextViews. благодаря. - person swift2geek; 31.07.2018

Почему бы просто не использовать 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

Вы можете найти более подробную информацию здесь

person MANN    schedule 03.09.2019
comment
Я только что попытался сегодня позвонить из UILabel, и приведенный выше код не работает. Я заменил dev.appl.com на tel://1234567. Возможно, этот ответ необходимо обновить. - person Pratik Somaiya; 03.06.2020

Возможное решение Swift 4.0 с использованием UIButton

     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)


    }
person Fidel    schedule 01.03.2018