web-dev-qa-db-ja.com

URL /電話クリック可能なUILabelを作成する方法は?

アプリにクリック可能なラベルを作成して、Safari Webページに移動したい。また、ユーザーがクリックするだけで電話番号に電話できるようにしたいですか?

アドバイスをありがとう

107
Rob

UITextViewを使用して、インスペクターでリンク、電話番号、その他のものの検出を選択できます。

125
Basel

UITextViewの代わりにUILabelを使用すると、テキストをハイパーリンクに変換するプロパティがあります。

Objective-C:

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

迅速:

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

これにより、リンクが自動的に検出されます。

詳細については、 ドキュメント をご覧ください。

93

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
28
Ramy Kfoury

カスタム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

}
12
Rohit Dhawan

これをUITextViewではなくUILabelで処理する場合は、次のような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)!)
            }
        }
    })

}}

このクラスは、この answer のコードを再利用して作成されました。属性付き文字列を作成するには、この answer を確認してください。 こちら 電話のURLを作成する方法を見つけることができます。

9
Bojan Bozovic

これを使用して、ラベルテキスト全体ではなく特定のテキストへの青色のリンクを作成するため、とても気に入りました: FRHyperLabel

Smartly applying hyperlink on Terms of Use

行うには:

  1. 上記のリンクからダウンロードして、FRHyperLabel.hFRHyperLabel.mをプロジェクトにコピーします。

  2. UILabelStoryboardをドラッグドロップし、画像に示すように、インスペクターを識別してカスタムクラス名をFRHyperLabelに定義します。

enter image description here

  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. そしてそれを実行します。
6
karan

UILabelの代わりにUITextViewを使用し、テキストをハイパーリンクに変換するプロパティがあります

スウィフトコード:

yourTextView.editable = false
yourTextView.dataDetectorTypes = UIDataDetectorTypes.All
//or
yourTextView.dataDetectorTypes = UIDataDetectorTypes.PhoneNumber
//or
yourTextView.dataDetectorTypes = UIDataDetectorTypes.Link
6
Thiago Arreguy
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
Harman