Как перехватить ссылку на ссылку в UITextView?

Возможно ли выполнить пользовательское действие, когда пользователь коснется автоопределенной телефонной ссылки в UITextView. Пожалуйста, не советуйте использовать UIWebView.

И, пожалуйста, не просто повторяйте текст из справки classов Apple, конечно, я его уже прочитал.

Благодарю.

Обновление: с ios10 ,

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction; 

Начиная с ios7 и более поздних UITextView имеет метод делегирования:

 - (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange *NS_DEPRECATED_IOS(7_0, 10_0, "Use textView:shouldInteractWithURL:inRange:forInteractionType: instead");* 

для перехвата кликов по ссылкам. И это лучший способ сделать это.

Для ios6 и ранее хороший способ сделать это – подclassифицировать UIApplication и перезаписать UIApplication адрес -(BOOL)openURL:(NSURL *)url

 @interface MyApplication : UIApplication { } @end @implementation MyApplication -(BOOL)openURL:(NSURL *)url{ if ([self.delegate openURL:url]) return YES; else return [super openURL:url]; } @end 

Вам нужно будет реализовать openURL: в вашем openURL: .

Теперь, чтобы запустить приложение с вашим новым подclassом UIApplication , найдите файл main.m в своем проекте. В этом маленьком файле, который загружает ваше приложение, обычно есть такая строка:

 int retVal = UIApplicationMain(argc, argv, nil, nil); 

Третий параметр – это имя classа для вашего приложения. Итак, заменив эту строку на:

 int retVal = UIApplicationMain(argc, argv, @"MyApplication", nil); 

Это помогло мне.

В iOS 7 или более поздней версии

Вы можете использовать следующий делегат UITextView. Метод:

 - (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange 

Текстовое представление вызывает этот метод, если пользователь нажимает или долго нажимает ссылку на URL. Реализация этого метода является необязательной. По умолчанию текстовое представление открывает приложение, ответственное за обработку URL-типа и передает ему URL-адрес. Вы можете использовать этот метод для запуска альтернативного действия, например отображения веб-контента по URL-адресу в веб-представлении в текущем приложении.

Важный:

Связи в текстовых представлениях интерактивны, только если текстовое представление является доступным, но не редактируется. То есть, если значение UITextView выбираемого свойства равно YES, а свойство isEditable равно NO.

Быстрая версия:

Ваша стандартная настройка UITextView должна выглядеть примерно так: не забудьте делегат и dataDetectorTypes.

 var textView = UITextView(x: 10, y: 10, width: CardWidth - 20, height: placeholderHeight) //This is my custom initializer textView.text = "dsfadsaf www.google.com" textView.selectable = true textView.dataDetectorTypes = UIDataDetectorTypes.Link textView.delegate = self addSubview(textView) 

После окончания вашего classа добавьте эту часть:

 class myVC: UIViewController { //viewdidload and other stuff here } extension MainCard: UITextViewDelegate { func textView(textView: UITextView, shouldInteractWithURL URL: NSURL, inRange characterRange: NSRange) -> Bool { //Do your stuff over here var webViewController = SVModalWebViewController(URL: URL) view.presentViewController(webViewController, animated: true, completion: nil) return false } } 

Для Swift 3

 textView.delegate = self extension MyTextView: UITextViewDelegate func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool { GCITracking.sharedInstance.track(externalLink: URL) return true } } 

или если цель равна> = IOS 10

 func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool 

С Swift 3 и i0S 10 самый простой способ взаимодействия с телефонными номерами, URL-адресами или адресами в UITextView – использовать UIDataDetectorTypes . В приведенном ниже коде показано, как отображать номер телефона в UITextView чтобы пользователь мог взаимодействовать с ним.

 import UIKit class ViewController: UIViewController { // Link this outlet to a UITextView in your Storyboard @IBOutlet weak var textView: UITextView! override func viewDidLoad() { super.viewDidLoad() textView.text = "+33687654321" textView.isUserInteractionEnabled = true // default: true textView.isEditable = false // default: true textView.isSelectable = true // default: true textView.dataDetectorTypes = [.phoneNumber] } } 

С помощью этого кода при нажатии на номер телефона появляется сообщение UIAlertController .


В качестве альтернативы вы можете использовать NSAttributedString :

 import UIKit class ViewController: UIViewController { // Link this outlet to a UITextView in your Storyboard @IBOutlet weak var textView: UITextView! override func viewDidLoad() { super.viewDidLoad() let phoneUrl = NSURL(string: "tel:+33687654321")! // "telprompt://+33687654321" also works let attributes = [NSLinkAttributeName: phoneUrl] let attributedString = NSAttributedString(string: "phone number", attributes: attributes) textView.attributedText = attributedString textView.isUserInteractionEnabled = true // default: true textView.isEditable = false // default: true textView.isSelectable = true // default: true } } 

С помощью этого кода при нажатии на атрибутную строку появится UIAlertController .


Тем не менее, вы можете выполнить некоторые пользовательские действия вместо того, чтобы UIAlertController всплывать при нажатии на номер телефона. Или вы можете захотеть, чтобы UIAlertController всплывал и выполнял ваши собственные действия в одно и то же время.

В обоих случаях вам нужно будет настроить UIViewController соответствие протоколу UITextViewDelegate и реализовать textView(_:shouldInteractWith:in:interaction:) . В приведенном ниже коде показано, как это сделать.

 import UIKit class ViewController: UIViewController, UITextViewDelegate { // Link this outlet to a UITextView in your Storyboard @IBOutlet weak var textView: UITextView! override func viewDidLoad() { super.viewDidLoad() textView.delegate = self textView.text = "+33687654321" textView.isUserInteractionEnabled = true textView.isEditable = false textView.isSelectable = true textView.dataDetectorTypes = [.phoneNumber] } func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool { /* perform your own custom actions here */ print(URL) return false // return true if you still want UIAlertController to pop up } } 

С помощью этого кода при нажатии на номер телефона не будет UIAlertController , и вместо этого вы получите следующую распечатку на консоли:

тел: +33687654321

У меня есть динамический контент в текстовом представлении, который может содержать ссылку. Функция shouldInteractWithURL вызывается только тогда, когда пользователь долго нажимает на ссылку, но не нажимает на ссылку. Переадресуйте, если у кого-то из друзей есть ссылка на него.

Ниже приведен код снайпера.

 UITextView *ltextView = [[UITextView alloc] init]; [ltextView setScrollEnabled:YES]; [ltextView setDataDetectorTypes:UIDataDetectorTypeLink]; ltextView.selectable = YES; [ltextView setEditable:NO]; ltextView.userInteractionEnabled = YES; ltextView.delegate = (id)self; ltextView.delaysContentTouches = NO; [self.view addsubview:ltextview]; - (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange{ [self.mActionDelegate userClickedOnImageLinkFromWebview:URL]; NSLog(@"urls is :- %@",URL); return FALSE; } 

Вышеупомянутый метод делегата не получает вызов по крану.

С уважением, Рохит Джанкар

Swift 4:

1) Создайте следующий class (подclassифицированный UITextView):

 import Foundation protocol QuickDetectLinkTextViewDelegate: class { func tappedLink() } class QuickDetectLinkTextView: UITextView { var linkDetectDelegate: QuickDetectLinkTextViewDelegate? override init(frame: CGRect, textContainer: NSTextContainer?) { super.init(frame: frame, textContainer: textContainer) } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { let glyphIndex: Int? = layoutManager.glyphIndex(for: point, in: textContainer, fractionOfDistanceThroughGlyph: nil) let index: Int? = layoutManager.characterIndexForGlyph(at: glyphIndex ?? 0) if let characterIndex = index { if characterIndex < textStorage.length { if textStorage.attribute(NSLinkAttributeName, at: characterIndex, effectiveRange: nil) != nil { linkDetectDelegate?.tappedLink() return self } } } return nil } } 

2) Где бы вы ни настраивали свой текст, сделайте следующее:

 //init, viewDidLoad, etc textView.linkDetectDelegate = self //outlet @IBOutlet weak var textView: QuickDetectLinkTextView! //change ClassName to your class extension ClassName: QuickDetectLinkTextViewDelegate { func tappedLink() { print("Tapped link, do something") } } 

Если вы используете раскадровку, убедитесь, что ваше текстовое представление выглядит так в инспекторе правой панели:
введите описание изображения здесь

Вуаля! Теперь вы сразу же получаете ссылку, а не URL-адрес должен использовать метод URL-адрес

Я сам этого не пробовал, но вы можете попробовать реализовать application:handleOpenURL: метод в application:handleOpenURL: приложения – похоже, что все openURL проходят через этот обратный вызов.

Не знаете, как перехватить обнаруженную ссылку на данные или какую функцию вам нужно выполнить. Но вы можете использовать метод didFeginEditing TextField для запуска теста / сканирования через текстовое поле, если вы знаете, что вы ищете … как сравнение текстовых строк, которые соответствуют формату ### – ### – ####, или начать с “www.” чтобы захватить эти поля, но вам нужно написать небольшой код, чтобы обнюхать строку текстовых полей, пересоздать то, что вам нужно, а затем извлечь его для использования вашей функции. Я не думаю, что это было бы так сложно, как только вы сузили именно то, что вы хотели, а затем сосредоточили внимание на том, что ваш оператор if () фильтрует до очень специфического соответствия шаблону того, что вам нужно.

Из couse это означает, что пользователь коснется текстового поля, чтобы активировать didBeginEditing (). Если это не тот тип взаимодействия с пользователем, который вы искали, вы могли бы просто использовать триггерный таймер, который начинается с ViewDidAppear () или другого на основе потребности и проходит через строку текстовых полей, а затем в конце вы пробегаете строку текстового поля методы, которые вы создали, вы просто отключите Таймер.

application:handleOpenURL: вызывается, когда другое приложение открывает ваше приложение, открывая URL-адрес с помощью схемы, поддерживаемой вашим приложением. Он не вызывается, когда ваше приложение начинает открывать URL-адрес.

Я думаю, что единственный способ сделать то, что хочет Владимир, – это использовать UIWebView вместо UITextView. Создайте свой controller представления UIWebViewDelegate, установите делегат UIWebView на controller представления и в controllerе представления выполните webView:shouldStartLoadWithRequest:navigationType: чтобы открыть [request URL] в представлении вместо того, чтобы выйти из приложения и открыть его в Mobile Safari.

  • objective C - Как использовать метод initWithCoder?
  • Пользовательский интерфейс UINavigationBar
  • Добавить анимированное изображение Gif в Iphone UIImageView
  • Создать случайное число в пределах диапазона?
  • Создание пользовательского UIKeyBoard для iPhone
  • Как обрабатывать дублируемую символьную ошибку от сторонних библиотек?
  • Удалить HTML-tags из NSString на iPhone
  • Как создать глобальные функции в Objective-C
  • Как написать таймер в Objective-C?
  • Масштабирование MKMapView для подгонки аннотаций?
  • Убедитесь, что вход в UITextField только числовой
  • Interesting Posts
    Давайте будем гением компьютера.