URL / Telefon tıklanabilir UILabel nasıl yapılır?


Yanıtlar:


134

Denetçide a'yı kullanabilir UITextViewve Bağlantılar, Telefon Numaraları ve diğer şeyler için Algılama'yı seçebilirsiniz.


2
N metin satırı barındırabilen kendi kendini yeniden boyutlandıran bir etiketim var. Bu etiketteki bağlantıları UITextView uygulamadan nasıl tıklanabilir yapabilirim.
2018

@bibscy daha sonra NSAttributedText'i kullanabilirsiniz. Bak stackoverflow.com/questions/1256887/...
Basel

95

UITextViewBunun yerine kullanın UILabelve metninizi köprüye dönüştürmek için bir özelliği vardır.

Objective-C:

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

Swift:

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

Bu, bağlantıları otomatik olarak algılayacaktır.

Ayrıntılar için belgelere bakın.


5
bu, bağlantıyı maviye boyar ve altını çizer, ancak en azından iOS 7'de tıklanabilir hale getirir.
Ben H

1
Swift kodu: yourTextView.editable = false; yourTextView.dataDetectorTypes = UIDataDetectorTypes.All;
Thiago Arreguy

5
soru UITextView ile değil, UILabel ile ilgilidir.
swift2geek

28

https://github.com/mattt/TTTAttributedLabel

Kesinlikle ihtiyacın olan şey bu. Ayrıca etiketiniz için altı çizili gibi öznitelikler uygulayabilir ve ona farklı renkler uygulayabilirsiniz. Tıklanabilir URL'lerin talimatlarını kontrol etmeniz yeterlidir.

Esas olarak, aşağıdaki gibi bir şey yaparsınız:

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

12

İstediğinizi özel bir UIButton ve setText yapabilir ve bununla bir yöntem ekleyebilirsiniz.

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
}

Yazı tipinin ayarlanması şu şekilde yapılır: button.titleLabel.font = [UIFont systemFontOfSize: size];
Leon

10

Bunun UITextView tarafından değil UILabel tarafından işlenmesini istiyorsanız, bunun gibi UILabel alt sınıfı yapabilirsiniz:

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

}}

Bu sınıf, bu kod yeniden kullanarak yapıldığı cevap . İlişkilendirilmiş dizeler yapmak için bu cevabı kontrol edin . Ve burada telefon url'lerinin nasıl yapıldığını bulabilirsiniz.


6

Bunu çok beğendim çünkü tüm etiket metninde değil, yalnızca belirli bir metne mavi renkle bağlantı oluşturuyor: FRHyperLabel

Kullanım Koşullarına akıllıca köprü uygulama

Yapmak:

  1. Yukarıdaki bağlantıyı ve kopyasından İndir FRHyperLabel.h, FRHyperLabel.mprojenize.

  2. Sürükle bırak UILabelsenin içinde Storyboardve tanımladığınız özel sınıf adı FRHyperLabelresimde görüldüğü gibi müfettişi belirlemek içinde.

görüntü açıklamasını buraya girin

  1. UILabel'inizi storyboard'dan viewController.h dosyanıza bağlayın

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

  1. Şimdi, viewController.m dosyanıza aşağıdaki kodu ekleyin.

`NSString * string = @" Yükleyerek Kullanım Koşullarını kabul ediyorum "; NSDictionary * attributes = @ {NSFontAttributeName: [UIFont preferFontForTextStyle: 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. Ve çalıştırın.

6

UILabel yerine UITextView kullanın ve metninizi köprüye dönüştürmek için bir özelliği vardır

Swift kodu:

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

4
Metin Görünümleri yerine UILabel'de nasıl kullanılacağı sorusu. Teşekkürler.
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

Neden sadece NSMutableAttributedString kullanılmıyor ?

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

Daha fazla bilgiyi burada bulabilirsiniz


Bugün UILabel'den bir arama yapmayı denedim ve yukarıdaki kod çalışmıyor. Dev.appl.com'u tel: // 1234567 ile değiştirdim . Bu cevabın güncellenmesi gerekebilir.
Pratik Somaiya

-1

Swift 4.2, Xcode 9.3 sürümü

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

UIButton kullanarak Swift 4.0 olası çözümü

     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)


    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.