Làm cách nào để tạo URL / Nhãn có thể nhấp vào điện thoại?


Câu trả lời:


134

Bạn có thể sử dụng a UITextViewvà chọn Dò tìm liên kết, Số điện thoại và những thứ khác trong trình kiểm tra.


2
Tôi có một nhãn tự thay đổi kích thước có thể chứa N dòng văn bản. Làm cách nào tôi có thể nhấp vào các liên kết trong nhãn này mà không cần triển khai UITextView.
bibscy

@bibscy thì bạn có thể sử dụng NSAttributedText. Nhìn vào stackoverflow.com/questions/1256887/…
Basel,

95

Sử dụng UITextViewthay vì UILabelvà nó có thuộc tính để chuyển đổi văn bản của bạn thành siêu liên kết.

Mục tiêu-C:

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

Nhanh:

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

Điều này sẽ tự động phát hiện các liên kết.

Xem tài liệu để biết chi tiết.


5
màu này màu xanh liên kết và gạch dưới nó, nhưng dường như để làm cho nó nhấp được, ít nhất là trên iOS 7.
Bến H

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

5
câu hỏi là về UILabel, không phải UITextView.
swift2geek,

28

https://github.com/mattt/TTTAttributedLabel

Đó chắc chắn là những gì bạn cần. Bạn cũng có thể áp dụng các thuộc tính cho nhãn của mình, như gạch dưới và áp dụng các màu khác nhau cho nhãn. Chỉ cần kiểm tra hướng dẫn cho các url có thể nhấp.

Chủ yếu, bạn thực hiện một số việc như sau:

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

12

Bạn có thể tạo UIButton và setText tùy chỉnh những gì bạn muốn và thêm một phương thức với điều đó.

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
}

Việc đặt phông chữ hiện đã được thực hiện bởi: button.titleLabel.font = [UIFont systemFontOfSize: size];
Leon

10

Nếu bạn muốn điều này được xử lý bởi UILabel chứ không phải UITextView, bạn có thể tạo lớp con của UILabel, như sau:

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

}}

Lớp này được tạo bằng cách sử dụng lại mã từ câu trả lời này . Để tạo chuỗi phân bổ, hãy kiểm tra câu trả lời này . Và ở đây bạn có thể tìm thấy cách tạo url điện thoại.


6

Sử dụng cái này, tôi rất thích nó vì chỉ tạo liên kết với màu xanh lam đến văn bản cụ thể chứ không phải trên toàn bộ văn bản nhãn: FRHyperLabel

Áp dụng siêu liên kết một cách thông minh về Điều khoản sử dụng

Làm:

  1. Tải về từ liên kết ở trên và bản sao FRHyperLabel.h, FRHyperLabel.mđể dự án của bạn.

  2. Kéo thả UILabelvào của bạn Storyboardvà xác định tên lớp tùy chỉnh để FRHyperLabelxác định trình kiểm tra như thể hiện trong hình ảnh.

nhập mô tả hình ảnh ở đây

  1. Kết nối UILabel của bạn từ bảng phân cảnh với tệp viewController.h của bạn

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

  1. Bây giờ trong tệp viewController.m của bạn, hãy thêm mã sau.

`NSString * string = @" Bằng cách tải lên, tôi đồng ý với Điều khoản sử dụng "; NSDictionary * thuộc tính = @ {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. Và chạy nó.

6

Sử dụng UITextView thay vì UILabel và nó có thuộc tính để chuyển đổi văn bản của bạn thành siêu liên kết

Mã Swift:

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

4
câu hỏi làm thế nào để sử dụng trong UILabel, thay vì TextView. cảm ơn.
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

Tại sao không chỉ sử dụng 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

Bạn có thể tìm thêm thông tin chi tiết tại đây


Hôm nay tôi vừa thử thực hiện cuộc gọi từ UILabel và mã trên không hoạt động. Tôi đã thay thế dev.appl.com bằng tel: // 1234567. Có thể câu trả lời này cần được cập nhật.
Pratik Somaiya

-1

Phiên bản Swift 4.2, Xcode 9.3

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 giải pháp khả thi sử dụng 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)


    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.