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

发布于 2024-07-24 15:13:01 字数 229 浏览 4 评论 0原文

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

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

有人以前这样做过或知道如何处理吗?

谢谢, 阿杰

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.

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

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

Thanks,
AJ

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

亢潮 2024-07-31 15:13:01

如果你使用的是OS3.0

你可以像下面这样做

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

If you are using OS3.0

you can do it like the following

textview.editable = NO;
textview.dataDetectorTypes = UIDataDetectorTypeAll;
镜花水月 2024-07-31 15:13:01

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

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.

陌伤ぢ 2024-07-31 15:13:01

Swift 3.0 +

从 swift 3.0 开始,如果您想以编程方式执行此操作,请使用以下代码。

textview.isEditable = false
textview.dataDetectorTypes = .all

或者,如果您有故事板

在此处输入图像描述

Swift 3.0 +

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

textview.isEditable = false
textview.dataDetectorTypes = .all

Or if you have a storyboard

enter image description here

若无相欠,怎会相见 2024-07-31 15:13:01

尽管这个问题非常古老。
不过,如果有人遇到同样的问题,

它也可以用作UILabel。 尽管
下面的解决方案可以完成这项工作:[不需要任何库..]

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

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

第 1 步。

import MessageUI

第 2 步。 添加委托

ViewController 类:UITextViewDelegate、MFMailComposeViewControllerDelegate{

第 3 步。< /strong> 从 StoryBoard 添加 textView IBOutlet

@IBOutlet weak var infoTextView: UITextView!

第 4 步。 在 vi​​ewDidload() 中调用以下方法

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
}

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

第 6 步。< /strong> 编写助手方法来打开 MailComposer 并调用应用程序

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)

}

第 7 步。 编写 MFMailComposer 的委托方法

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

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

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

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

这是该图像..

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..]

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

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

Step 1.

import MessageUI

Step 2. Add the delegate

class ViewController: UITextViewDelegate, MFMailComposeViewControllerDelegate{

Step 3. Add the textView IBOutlet From StoryBoard

@IBOutlet weak var infoTextView: UITextView!

Step 4. Call the below method in your 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

@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

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

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

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

Set the below properties to Use it as a UILabel

Here's the image for that..

鱼忆七猫命九 2024-07-31 15:13:01

如果您想自动检测链接、电子邮件等,请确保“isSelectable”设置为 true。

textview.isSelectable = true
textview.editable = false
textview.dataDetectorTypes = .all

If you want to auto detect links, email etc Please make sure "isSelectable" is set to true.

textview.isSelectable = true
textview.editable = false
textview.dataDetectorTypes = .all
桃酥萝莉 2024-07-31 15:13:01

第 1 步:创建 UITextview 的子类并重写 canBecomeFirstResponder 函数

KDTextView.h 代码:

@interface KDTextView : UITextView

@end

KDTextView.m 代码:​​

#import "KDTextView.h"

// Textview to disable the selection options

@implementation KDTextView

- (BOOL)canBecomeFirstResponder {
    return NO;
}

@end

第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];

第3步:实现委托方法

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

Step 1. Create a subclass of UITextview and override the canBecomeFirstResponder function

KDTextView.h Code:

@interface KDTextView : UITextView

@end

KDTextView.m Code:

#import "KDTextView.h"

// Textview to disable the selection options

@implementation KDTextView

- (BOOL)canBecomeFirstResponder {
    return NO;
}

@end

Step 2. Create the Textview using subclass KDTextView

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;
}
蓝天 2024-07-31 15:13:01

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

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".

故乡的云 2024-07-31 15:13:01

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

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

希望这会有所帮助有人节省了宝贵的时间。 快乐编码:)

Swift 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.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文