Wie mache ich URL / Telefon klickbar UILabel?


Antworten:


134

Sie können UITextViewim Inspektor a verwenden und Erkennung für Links, Telefonnummern und andere Dinge auswählen.


2
Ich habe ein Etikett mit Größenänderung, das N Textzeilen aufnehmen kann. Wie kann ich die Links in diesem Label anklickbar machen, ohne UITextView zu implementieren?
Bibscy

@bibscy dann können Sie den NSAttributedText verwenden. Schauen Sie auf stackoverflow.com/questions/1256887/…
Basel

95

Verwenden Sie UITextViewanstelle von UILabelund es hat eine Eigenschaft, um Ihren Text in einen Hyperlink zu konvertieren.

Ziel c:

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

Schnell:

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

Dadurch werden Links automatisch erkannt.

Einzelheiten finden Sie in der Dokumentation .


5
Dies färbt den Link blau und unterstreicht ihn, scheint ihn aber zumindest unter iOS 7 anklickbar zu machen.
Ben H

1
Schneller Code: yourTextView.editable = false; yourTextView.dataDetectorTypes = UIDataDetectorTypes.All;
Thiago Arreguy

5
Die Frage bezieht sich auf UILabel, nicht auf UITextView.
swift2geek

28

https://github.com/mattt/TTTAttributedLabel

Das ist definitiv was du brauchst. Sie können auch Attribute für Ihr Etikett anwenden, z. B. Unterstreichung, und verschiedene Farben darauf anwenden. Überprüfen Sie einfach die Anweisungen für anklickbare URLs.

Hauptsächlich machen Sie so etwas wie das Folgende:

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

12

Sie können einen benutzerdefinierten UIButton und setText erstellen, was immer Sie möchten, und damit eine Methode hinzufügen.

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
}

Das Festlegen der Schriftart erfolgt jetzt durch: button.titleLabel.font = [UIFont systemFontOfSize: size];
Leon

10

Wenn Sie möchten, dass dies von UILabel und nicht von UITextView behandelt wird, können Sie eine UILabel-Unterklasse wie die folgende erstellen:

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)!)
            }
        }
    })

}}

Diese Klasse wurde erstellt, indem Code aus dieser Antwort wiederverwendet wurde . Überprüfen Sie diese Antwort , um zugeordnete Zeichenfolgen zu erstellen . Und hier finden Sie, wie Sie Telefon-URLs erstellen.


6

Verwenden Sie dies, es hat mir so gut gefallen, da eine Verknüpfung mit blauer Farbe zu einem bestimmten Text nur nicht auf dem gesamten Etikettentext erstellt wird: FRHyperLabel

Intelligentes Anwenden von Hyperlinks auf Nutzungsbedingungen

Machen:

  1. Download Link oben und Kopie FRHyperLabel.h, FRHyperLabel.mzu Ihrem Projekt.

  2. Ziehen Sie die Dropdown-Liste UILabelin Ihren Storyboardund definieren Sie den benutzerdefinierten Klassennamen, FRHyperLabelum den Inspektor wie in der Abbildung gezeigt zu identifizieren.

Geben Sie hier die Bildbeschreibung ein

  1. Verbinden Sie Ihr UILabel vom Storyboard mit Ihrer Datei viewController.h

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

  1. Fügen Sie nun in Ihrer viewController.m-Datei den folgenden Code hinzu.

`NSString * string = @" Durch das Hochladen stimme ich den Nutzungsbedingungen zu "; NSDictionary * Attribute = @ {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. Und lass es laufen.

6

Verwenden Sie UITextView anstelle von UILabel und es verfügt über eine Eigenschaft, mit der Sie Ihren Text in einen Hyperlink konvertieren können

SWIFT-Code:

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

4
die Frage, wie man UILabel anstelle von TextViews verwendet. Vielen Dank.
swift2geek

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)
        }
    }
}

0

Warum nicht einfach NSMutableAttributedString verwenden ?

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

Weitere Details finden Sie hier


Ich habe heute gerade versucht, einen Anruf von UILabel zu tätigen, und der obige Code funktioniert nicht. Ich habe dev.appl.com durch tel: // 1234567 ersetzt. Möglicherweise muss diese Antwort aktualisiert werden.
Pratik Somaiya

-1

Swift 4.2, Xcode 9.3 Version

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(self.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;
            }

        }
    }

    @objc 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(NSAttributedStringKey.link, 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)!)
                }
            }
        })

    }}

-3

Swift 4.0 mögliche Lösung mit 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)


    }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.