ios 如何让 UITextView 检测网站、邮件和电话号码的链接

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/995219/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 16:01:56  来源:igfitidea点击:

How to make UITextView detect links for website, mail and phone number

iosobjective-chyperlinkuitextview

提问by AJ.

I have a UITextView object. The text in UIView has a phone number, mail link, a website link. I want to show them as links with following functionality.

我有一个 UITextView 对象。UIView 中的文本有电话号码、邮件链接、网站链接。我想将它们显示为具有以下功能的链接。

When someone taps on URL - Safari should open the the website. When someone taps on email link - Mail should open up with my address in to field When someone taps on phone number - Phone application should call the number

当有人点击 URL 时 - Safari 应该打开该网站。当有人点击电子邮件链接时 - 邮件应该打开我的地址字段 当有人点击电话号码时 - 电话应用程序应该拨打该号码

Has anyone done this before or knows how to handle it?

有没有人以前做过这个或知道如何处理它?

Thanks, AJ

谢谢,阿杰

回答by

If you are using OS3.0

如果您使用的是 OS3.0

you can do it like the following

你可以像下面这样

textview.editable = NO;
textview.dataDetectorTypes = UIDataDetectorTypeAll;

回答by Andrew Hershberger

A note on detecting email addresses: The Mail app must be installed (it's not on the iOS Simulator) for email links to open a message compose screen.

关于检测电子邮件地址的注意事项:必须安装邮件应用程序(它不在 iOS 模拟器上),电子邮件链接才能打开邮件撰写屏幕。

回答by Fangming

Swift 3.0 +

斯威夫特 3.0 +

As of swift 3.0, use the following code if you want to do it programmatically.

从 swift 3.0 开始,如果要以编程方式执行,请使用以下代码。

textview.isEditable = false
textview.dataDetectorTypes = .all

Or if you have a storyboard

或者如果你有一个故事板

enter image description here

在此处输入图片说明

回答by Yash Bedi

Though the Question is super Old. Still if anyone faces the same issue,

虽然问题是超级老。如果有人面临同样的问题,

Also it can be used as a UILabel. Though Below solution will do the job : [There isn't a need for any library..]

它也可以用作UILabel。虽然下面的解决方案可以完成这项工作:[不需要任何图书馆..]

So I've used MFMailcomposer()and UITexView[ Code is in Swift 3.0 - Xcode 8.3.2 ]

所以我使用了MFMailcomposer()UITexView [代码在 Swift 3.0 - Xcode 8.3.2]

A 100% Crash Proof and Working Code Handles all the corner cases. =D

100% 防碰撞和工作代码处理所有极端情况。=D

Step 1.

第1步。

import MessageUI

Step 2.Add the delegate

步骤 2.添加委托

class ViewController: UITextViewDelegate, MFMailComposeViewControllerDelegate{

class ViewController: UITextViewDelegate, MFMailComposeViewControllerDelegate{

Step 3.Add the textView IBOutlet From StoryBoard

步骤 3.从 StoryBoard 添加 textView IBOutlet

@IBOutlet weak var infoTextView: UITextView!

Step 4.Call the below method in your viewDidload()

步骤 4.在 viewDidload() 中调用以下方法

func addInfoToTextView()  {
    let attributedString = NSMutableAttributedString(string: "For further info call us on : \(phoneNumber)\nor mail us at : \(email)")
    attributedString.addAttribute(NSLinkAttributeName, value: "tel://", range: NSRange(location: 30, length: 10))
    attributedString.addAttribute(NSLinkAttributeName, value: "mailto:", range: NSRange(location: 57, length: 18))
    self.infoTextView.attributedText = attributedString
    self.infoTextView.linkTextAttributes = [NSForegroundColorAttributeName:UIColor.blue, NSUnderlineStyleAttributeName:NSNumber(value: 0)]
    self.infoTextView.textColor = .white
    self.infoTextView.textAlignment = .center
    self.infoTextView.isEditable = false
    self.infoTextView.dataDetectorTypes = UIDataDetectorTypes.all
    self.infoTextView.delegate = self
}

Step 5.Implement delegate methods for TextView

步骤 5.为 TextView 实现委托方法

@available(iOS, deprecated: 10.0)
func textView(_ textView: UITextView, shouldInteractWith url: URL, in characterRange: NSRange) -> Bool {
    if (url.scheme?.contains("mailto"))! && characterRange.location > 55{
        openMFMail()
    }
    if (url.scheme?.contains("tel"))! && (characterRange.location > 29 && characterRange.location < 39){
        callNumber()
    }
    return false
}

//For iOS 10
@available(iOS 10.0, *)
func textView(_ textView: UITextView, shouldInteractWith url: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
    if (url.scheme?.contains("mailto"))! && characterRange.location > 55{
        openMFMail()
    }
    if (url.scheme?.contains("tel"))! && (characterRange.location > 29 && characterRange.location < 39){
        callNumber()
    }
    return false
}

Step 6.Write the helper Methods to open MailComposer and Call App

步骤 6.编写帮助方法来打开 MailComposer 和 Call App

func callNumber() {
    if let phoneCallURL = URL(string: "tel://\(phoneNumber)")
    {
        let application:UIApplication = UIApplication.shared
        if (application.canOpenURL(phoneCallURL))
        {
            let alert = UIAlertController(title: "Call", message: "\(phoneNumber)", preferredStyle: UIAlertControllerStyle.alert)
            if #available(iOS 10.0, *)
            {
                alert.addAction(UIAlertAction(title: "Call", style: .cancel, handler: { (UIAlertAction) in
                    application.open(phoneCallURL, options: [:], completionHandler: nil)
                }))
            }
            else
            {
                alert.addAction(UIAlertAction(title: "Call", style: .cancel, handler: { (UIAlertAction) in
                    application.openURL(phoneCallURL)
                }))
            }

            alert.addAction(UIAlertAction(title: "cancel", style: .default, handler: nil))
            self.present(alert, animated: true, completion: nil)
        }
    }
    else
    {
        self.showAlert("Couldn't", message: "Call, cannot open Phone Screen")
    }
}
func openMFMail(){
    let mailComposer = MFMailComposeViewController()
    mailComposer.mailComposeDelegate = self
    mailComposer.setToRecipients(["\(email)"])
    mailComposer.setSubject("Subject..")
    mailComposer.setMessageBody("Please share your problem.", isHTML: false)
    present(mailComposer, animated: true, completion: nil)

}

Step 7.Write MFMailComposer's Delegate Method

步骤 7.编写 MFMailComposer 的 Delegate 方法

func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
    switch result {
    case .cancelled:
        print("Mail cancelled")
    case .saved:
        print("Mail saved")
    case .sent:
        print("Mail sent")
    case .failed:
        print("Mail sent failure: \(String(describing: error?.localizedDescription))")
    default:
        break
    }
    controller.dismiss(animated: true, completion: nil)
}

That's it you're Done... =D

这样你就完成了... =D

Here is the swift file for the above code : textViewWithEmailAndPhone.swift

这是上述代码的 swift 文件: textViewWithEmailAndPhone.swift

Set the below properties to Use it as a UILabel

设置以下属性以将其用作 UILabel

Here's the image for that..

这是图片..

回答by Kuldeep Singh

Step 1. Create a subclass of UITextview and override the canBecomeFirstResponderfunction

Step 1. 创建 UITextview 的子类并覆盖canBecomeFirstResponder函数

KDTextView.h Code:

KDTextView.h 代码:

@interface KDTextView : UITextView

@end

KDTextView.m Code:

KDTextView.m 代码:

#import "KDTextView.h"

// Textview to disable the selection options

@implementation KDTextView

- (BOOL)canBecomeFirstResponder {
    return NO;
}

@end

Step 2. Create the Textview using subclass KDTextView

步骤 2. 使用子类 KDTextView 创建 Textview

KDTextView*_textView = [[KDTextView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    [_textView setScrollEnabled:false];
    [_textView setEditable:false];
    _textView.delegate = self;
    [_textView setDataDetectorTypes:UIDataDetectorTypeAll];
    _textView.selectable = YES;
    _textView.delaysContentTouches = NO;
    _textView.userInteractionEnabled = YES;
    [self.view addSubview:_textView];

Step 3: Implement the delegate method

第三步:实现委托方法

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange
{
    return true;
}

回答by Ed Marty

I'm curious, do you have control over the text shown? If so, you should probably just stick it in a UIWebView and throw some links in there to do it "the right way".

我很好奇,你能控制显示的文字吗?如果是这样,您可能应该将其粘贴在 UIWebView 中并在其中放置一些链接以“以正确的方式”执行此操作。

回答by Prashant Gaikwad

Swift 4.2 Xcode 10.1

斯威夫特 4.2 Xcode 10.1

func setupContactUsTextView() {
        let text = NSMutableAttributedString(string: "Love your App, but need more help? Text, Call (123) 456-1234 or email ")
        if let font = UIFont(name: "Calibri", size: 17) {
            text.addAttribute(NSAttributedStringKey.font,
                              value: font,
                              range: NSRange(location: 0, length: text.length))
        } else {
            text.addAttribute(NSAttributedStringKey.font,
                              value: UIFont.systemFont(ofSize: 17),
                              range: NSRange(location: 0, length: text.length))
        }
        text.addAttribute(NSAttributedStringKey.foregroundColor,
                          value: UIColor.init(red: 112/255, green: 112/255, blue: 112/255, alpha: 1.0),
                          range: NSRange(location: 0, length: text.length))
        text.addAttribute(NSAttributedStringKey.link, value: "tel://", range: NSRange(location: 49, length: 15))
        let interactableText = NSMutableAttributedString(string: "[email protected]")
        if let font = UIFont(name: "Calibri", size: 17) {
            interactableText.addAttribute(NSAttributedStringKey.font,
                                          value: font,
                                          range: NSRange(location: 0, length: interactableText.length))
        } else {
            interactableText.addAttribute(NSAttributedStringKey.font,
                                          value: UIFont.systemFont(ofSize: 17),
                                          range: NSRange(location: 0, length: interactableText.length))
        }
        interactableText.addAttribute(NSAttributedStringKey.link,
                                      value: "[email protected]",
                                      range: NSRange(location: 0, length: interactableText.length))
        interactableText.addAttribute(NSAttributedStringKey.underlineStyle,
                                      value: NSUnderlineStyle.styleSingle.rawValue,
                                      range: NSRange(location: 0, length: interactableText.length))
        text.append(interactableText)
        videoDescTextView.attributedText = text
        videoDescTextView.textAlignment = .center
        videoDescTextView.isEditable = false
        videoDescTextView.isSelectable = true
        videoDescTextView.delegate = self
    }

    func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
        if (characterRange.location > 48 && characterRange.location < 65){
            print("open phone")
        }else{
            print("open gmail")
        }
        return false
    }

Steps - 1. Set the delegate to your text field and don't forget to implement UITextViewDelegate 2. Take the textView outlet - @IBOutlet weak var videoDescTextView: UITextView! 3. Add these two functions given above. This function shows how to detect phone numbers, email from textView, how to underline your email id, how to give custom color to your text, custom font, how to call a function when tapping on phone or email, etc.

步骤 - 1. 将委托设置为您的文本字段,不要忘记实现 UITextViewDelegate 2. 使用 textView 插座 - @IBOutlet weak var videoDescTextView: UITextView!3. 添加上面给出的这两个函数。该函数展示了如何检测电话号码、textView 中的电子邮件、如何为电子邮件 ID 加下划线、如何为文本自定义颜色、自定义字体、如何在点击电话或电子邮件时调用函数等。

Hope this will help someone to save their valuable time. Happy Coding :)

希望这能帮助某人节省宝贵的时间。快乐编码:)