Respostas:
Atualização: De IOS10,
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange interaction:(UITextItemInteraction)interaction;
De ios7and Later UITextView
tem o método delegate:
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange *NS_DEPRECATED_IOS(7_0, 10_0, "Use textView:shouldInteractWithURL:inRange:forInteractionType: instead");*
para interceptar os cliques em links. E esta é a melhor forma de o fazer.
Para iOS6e antes, uma boa maneira de fazer isso é subclassificando UIApplication
e substituindo o-(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
Você precisará implementar openURL:
em seu delegado.
Agora, para que o aplicativo comece com sua nova subclasse de UIApplication
, localize o arquivo main.m em seu projeto. Nesse pequeno arquivo que inicializa seu aplicativo, geralmente há esta linha:
int retVal = UIApplicationMain(argc, argv, nil, nil);
O terceiro parâmetro é o nome da classe do seu aplicativo. Então, substituindo esta linha por:
int retVal = UIApplicationMain(argc, argv, @"MyApplication", nil);
Isso funcionou para mim.
UIApplication
e substituir a implementação openURL. Embora dessa forma seja complicado (mas não impossível) fazer referência à implementação original.
No iOS 7 ou posterior
Você pode usar o seguinte método de delegado UITextView:
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange
A visualização de texto chama esse método se o usuário tocar ou manter pressionado o link do URL. A implementação deste método é opcional. Por padrão, a visualização de texto abre o aplicativo responsável por manipular o tipo de URL e passa a URL. Você pode usar este método para acionar uma ação alternativa, como exibir o conteúdo da web no URL em uma visualização da web no aplicativo atual.
Importante:
Os links em visualizações de texto são interativos apenas se a visualização de texto for selecionável, mas não editável. Ou seja, se o valor de UITextView, a propriedade selecionável for YES e a propriedade isEditable for NO.
UIWebView
se quiser fazer com que algum outro texto seja o link e não a própria URL. A <a>
etiqueta ainda é a melhor maneira de ir nesse caso.
Para 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
}
}
ou se o alvo for> = IOS 10
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool
Com o Swift 5 e iOS 12, você pode usar um dos três padrões a seguir para interagir com links em a UITextView
.
UITextView
a dataDetectorTypes
propriedade de.A maneira mais simples de interagir com números de telefone, urls ou endereços em um UITextView
é usar dataDetectorTypes
propriedade. O código de exemplo abaixo mostra como implementá-lo. Com este código, quando o usuário toca no número do telefone, um UIAlertController
aparece.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let textView = UITextView()
textView.text = "Phone number: +33687654321"
textView.isUserInteractionEnabled = true
textView.isEditable = false
textView.isSelectable = true
textView.dataDetectorTypes = [.phoneNumber]
textView.isScrollEnabled = false
textView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(textView)
textView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
textView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
textView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor).isActive = true
}
}
UITextViewDelegate
o textView(_:shouldInteractWith:in:interaction:)
método deSe quiser realizar alguma ação personalizada em vez de fazer um UIAlertController
pop-up ao tocar em um número de telefone durante o uso dataDetectorTypes
, você deve fazer o seuUIViewController
conformidade com o UITextViewDelegate
protocolo e implementar textView(_:shouldInteractWith:in:interaction:)
. O código abaixo mostra como implementá-lo:
import UIKit
class ViewController: UIViewController, UITextViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let textView = UITextView()
textView.delegate = self
textView.text = "Phone number: +33687654321"
textView.isUserInteractionEnabled = true
textView.isEditable = false
textView.isSelectable = true
textView.dataDetectorTypes = [.phoneNumber]
textView.isScrollEnabled = false
textView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(textView)
textView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
textView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
textView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor).isActive = true
}
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
/* perform your own custom actions here */
print(URL) // prints: "tel:+33687654321"
return false // return true if you also want UIAlertController to pop up
}
}
NSAttributedString
eNSAttributedString.Key.link
Como alternativa, você pode usar NSAttributedString
e definir um URL
para seu NSAttributedString.Key.link
atributo. O código de exemplo abaixo mostra uma possível implementação dele. Com este código, quando o usuário toca na string atribuída, um UIAlertController
aparece.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let attributedString = NSMutableAttributedString(string: "Contact: ")
let phoneUrl = NSURL(string: "tel:+33687654321")! // "telprompt://+33687654321" also works
let attributes = [NSAttributedString.Key.link: phoneUrl]
let phoneAttributedString = NSAttributedString(string: "phone number", attributes: attributes)
attributedString.append(phoneAttributedString)
let textView = UITextView()
textView.attributedText = attributedString
textView.isUserInteractionEnabled = true
textView.isEditable = false
textView.isSelectable = true
textView.isScrollEnabled = false
textView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(textView)
textView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
textView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
textView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor).isActive = true
}
}
Versão Swift:
Sua configuração UITextView padrão deve ser semelhante a isto, não se esqueça do delegate e 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)
Depois que sua aula terminar, adicione esta peça:
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 4:
1) Crie a seguinte classe (subclasse 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) Onde quer que você configure sua visualização de texto, faça o seguinte:
//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")
}
}
Se você estiver usando um storyboard, certifique-se de que sua visualização de texto tenha a seguinte aparência no painel direito do inspetor de identidade:
Voila! Agora você obtém o link toque imediatamente em vez de quando o URL deve Interactar com o método de URL
Não tenho certeza de como você interceptaria o link de dados detectado ou que tipo de função você precisa executar. Mas você pode ser capaz de utilizar o método didBeginEditing TextField para executar um teste / varredura através do campo de texto se você souber o que está procurando ... como comparar strings de texto que atendem ao formato ### - ### - ####, ou comece com "www." para pegar esses campos, mas você precisaria escrever um pequeno código para farejar a string textfields, reconectar o que você precisa e, em seguida, extraí-lo para uso de sua função. Eu não acho que isso seria tão difícil, uma vez que você restringiu exatamente o que você queria e então focou seus filtros de instrução if () em um padrão de correspondência muito específico do que você precisava.
Obviamente, isso implica que o usuário irá tocar na caixa de texto para ativar o didBeginEditing (). Se esse não for o tipo de interação do usuário que você está procurando, você pode usar um temporizador de gatilho, que começa em ViewDidAppear () ou outro com base na necessidade e percorre a string textfields, então, no final de você, execute a string textfield métodos que você construiu, basta desligar o cronômetro.
application:handleOpenURL:
é chamado quando outro aplicativo abre seu aplicativo abrindo uma URL com um esquema que seu aplicativo suporta. Não é chamado quando seu aplicativo começa a abrir um URL.
Acho que a única maneira de fazer o que Vladimir deseja é usar um UIWebView em vez de um UITextView. Faça seu controlador de visualização implementar UIWebViewDelegate, definir o delegado de UIWebView para o controlador de visualização e, no controlador de visualização, implementar webView:shouldStartLoadWithRequest:navigationType:
para abrir [request URL]
em uma visualização em vez de encerrar seu aplicativo e abri-lo no Mobile Safari.