En iOS 7 app, tengo un UITextView con un enlace, pero pulsando el enlace no de fuego. Sólo responde a un torpe «toque y mantenga». Quiero responder tan pronto como un usuario pulsa sobre ella, como la forma de un UIWebView enlace pulsa en obras. Aquí es mi configuración:

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:@"Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."];
    [text addAttribute:NSLinkAttributeName value:@"myurl://tapped" range:NSMakeRange(6, 16)];

    self.textView.attributedText = text;
    self.textView.editable = NO;
    self.textView.delaysContentTouches = NO;
}

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange
{
    if ([[URL scheme] isEqualToString:@"myurl"])
    {
        //Handle tap

        return NO;
    }

    return YES;
}

La Documentación de Apple para el shouldInteractWithURL método de los estados: «La vista de texto llama a este método si el usuario pulsa o largo de las prensas de la URL del enlace». Al pulsar el botón está trabajando, pero el grifo no parece funcionar.

¿Alguien sabe cómo conseguir esto para responder de inmediato?

  • Enlace pulsa en el reconocimiento se retrasa sigue ocurriendo en iOS9 :((((((
InformationsquelleAutor lehn0058 | 2014-03-13

7 Comentarios

  1. 14

    Es el UITextView seleccionables?. Tratar con:

    self.textView.selectable = YES;

    Edición:

    Estoy empezando a pensar que tal vez una larga prensa es la única forma de fuego, contrario a lo que apple dice. Marque esta enlace, tal vez pueda ayudar.

    • Es seleccionable. El problema no es que no funciona el link. Es que el usuario tiene que hacer un retraso en la tocan.
    • Podría ser un bug fija ahora en iOS 7.1? enlace. Intenta desactivar el desplazamiento como solución.
    • Estoy usando 7.1 – acaba de actualizar ayer y verificada esta es la forma en que funciona tanto en la 7.0 y 7.1.
    • Encontrar posibles soluciones: [self.textView setText:nil] antes de establecer la dirección URL. self.textView.dataDetectorTypes = UIDataDetectorTypeLink; [self.textView.scrollEnabled:NO];
    • Gracias – traté de estas configuraciones, pero no hubo ningún cambio en el comportamiento.
    • Estoy empezando a pensar que tal vez una larga prensa es la única forma de fuego, contrario a lo que apple dice. Marque esta enlace, tal vez pueda ayudar.
    • nnarayann, va a necesitar un par de modificaciones, pero yo esto debería darme lo que quiero. Si agrega esta sugerencia en una respuesta, voy a marcar el suyo como correcta.
    • Hecho. Me alegro de ayuda.
    • Me estoy enfrentando el mismo problema que el usuario tiene que pulsar el botón de un enlace detectado por dataDetectorTypes = UIDataDetectorTypeLink. Parece CCHLinkTextView no admite rápida pulsando los enlaces URL, lamentablemente.

  2. 36

    Si quieres ir con un nativo UITextView, usted puede agregar un toque de reconocimiento a su textview y obtener los atributos de la cadena en el toque ubicación. Cuando usted encuentra un enlace, se puede abrir inmediatamente.

    Escribí una idea que resuelve esto para iOS 7/8. Es ligera extensión de UITextView que también envía -[UITextViewDelegate textView:shouldInteractWithURL:inRange:] y expone la interna toque gesto de reconocimiento.

    https://gist.github.com/benjaminbojko/c92ac19fe4db3302bd28

    Aquí está un ejemplo rápido:El siguiente ejemplo sólo funciona en iOS 8. Ver la esencia de arriba para iOS 7 + 8.

    Añadir su toque de reconocimiento:

    //...
    
    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tappedTextView:)];
    [myTextView addGestureRecognizer:tapRecognizer];
    myTextView.selectable = YES; //otherwise the gesture won't recognize
    
    //...

    Y agregar su devolución de llamada:

    - (void)tappedTextView:(UITapGestureRecognizer *)tapGesture {
        if (tapGesture.state != UIGestureRecognizerStateEnded) {
            return;
        }
    
        UITextView *textView = (UITextView *)tapGesture.view;
        CGPoint tapLocation = [tapGesture locationInView:textView];
        UITextPosition *textPosition = [textView closestPositionToPoint:tapLocation];
        NSDictionary *attributes = [textView textStylingAtPosition:textPosition inDirection:UITextStorageDirectionForward];
    
        NSURL *url = attributes[NSLinkAttributeName];
    
        if (url) {
            [[UIApplication sharedApplication] openURL:url];
        }
    }

    Y swift versión:

    Toque de reconocimiento:

    let tapRecognizer = UITapGestureRecognizer(target: self, action: Selector("tappedTextView:"))
    myTextView.addGestureRecognizer(tapRecognizer)
    myTextView.selectable = true

    De devolución de llamada:

    func tappedTextView(tapGesture: UIGestureRecognizer) {
    
            let textView = tapGesture.view as! UITextView
            let tapLocation = tapGesture.locationInView(textView)
            let textPosition = textView.closestPositionToPoint(tapLocation)
            let attr: NSDictionary = textView.textStylingAtPosition(textPosition, inDirection: UITextStorageDirection.Forward)
    
            if let url: NSURL = attr[NSLinkAttributeName] as? NSURL {
                UIApplication.sharedApplication().openURL(url)
            }
    
            }
    • Esto es exactamente lo que yo necesitaba. Dos notas al margen, sin embargo: 1: el textView debe ser seleccionable para que esto funcione (ojalá pudiera deshabilitar) 2: el NSLinkAttributeName clave de attributes produce una NSURL, por lo que el código anterior produce un error en la URLWithString parte
    • gracias! He editado mi respuesta original para reflejar sus puntos.
    • He intentado esto en iOS 7, y parece que el textView no puede encontrar el atributo link a todos. Ha tenido suerte con esto en iOS 7?
    • A la derecha, yo recuerdo haber algunas cruz-problemas de versión. Finalmente, se hizo un poco difícil conseguir que los atributos con textStylingAtPosition:inDirection: en iOS 7. Supongo que tenía que ver con la textPosition que tiene una longitud de 0, y por lo tanto las atribuidas cadena no tenía personajes a la realidad de host de cualquier información de enlace. Sólo un pensamiento. En última instancia, escribí esta Esencia que me funciona en iOS 7 y 8: gist.github.com/benjaminbojko/c92ac19fe4db3302bd28
    • 32 más votos!
    • Tenga en cuenta que en lugar de «NSURL», podría ser un «NSString» dependiendo de cómo se configure la dirección URL.
    • Swift 4: @objc func tappedTextView(tapGesture: UIGestureRecognizer) { let textView = tapGesture.view as! UITextView let tapLocation = tapGesture.location(in: textView) let textPosition = textView.closestPosition(to: tapLocation) let attr = textView.textStyling(at: textPosition!, in: .forward)! if let url: URL = attr[NSAttributedStringKey.link.rawValue] as? URL { UIApplication.shared.open(url, options: [:], completionHandler: nil) } }

  3. 7

    Como nnarayann mencionado, CCHLinkTextView evita el problema de la demora del toque de reconocimiento. Esta biblioteca implementa su propio gesto de reconocimiento y ahora está disponible en la versión 1.0.

    • Buena biblioteca! Tomó sólo 2 minutos a incluir la vaina y ajustar el código existente en mi swift proyecto. Funciona a la perfección. Además, el atributo toma un valor de cualquier tipo en lugar de un NSURL. Es perfecto si usted necesita para pasar a otra cosa, como un índice. Gracias!
    • las obras buenas……
  4. 3

    Swift 4 solución


    • Maneja enlaces, pulsa gesto de reconocimiento de
    • Si isSelectable es true o false, funciona

    let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleLinkTap(_:)))
    textView.addGestureRecognizer(tapRecognizer)
    
    @objc func handleLinkTap(_ recognizer: UITapGestureRecognizer) {
        let tapLocation = recognizer.location(in: textView)
        guard
            let textPosition = textView.closestPosition(to: tapLocation),
            let url = textView.textStyling(at: textPosition, in: .forward)?[NSAttributedStringKey.link.rawValue],
            let urlString = (url as? String) ?? (url as? URL)?.absoluteString,
            urlString == "myurl"
        else { return }
    
        let url = URL(string: urlString)!
        //Do whatever you want with this URL, such as
        UIApplication.shared.openURL(url)
    }
    • El uso de este: let urlString = textView.textStyling(at: textPosition, in: .forward)?[NSAttributedStringKey.link.rawValue] as? URL, urlString == "myurl" else { return } en Lugar de: let urlString = textView.textStyling(at: textPosition, in: .forward)?[NSAttributedStringKey.link.rawValue] as? String, urlString == "myurl" else { return }
    • Estás seguro? porque (como recuerdo) he intentado lanzar el resultado como URL, supongo que no, voy a volver a comprobar para asegurarse de que (pronto como sea posible) si funciona
    • Sí, estoy seguro. Verificación de tu lado, así
    • He de averiguar, depende de enlace atributo. Me han dado la dirección URL. También puede tomar de Cadena
    • Volver a revisar @RasheshBosamiya, valor para textStyling[NSAttributedStringKey.link.rawValue] es NSString que produce un error en la fundición a la dirección URL, puede crear URL.init(string: urlString) si es necesario
    • Sí, Han proporcionado una dirección URL como atributo de vínculo. Gracias
    • Gracias por tus comentarios, me salvó hoy depende de enlace atributo. respuesta actualizada para apoyar ambos casos
    • Genial!!! Es bueno saber que después de poco tiempo. Gracias por estar en contacto.

  5. 2

    A veces no funciona en el Simulador de iOS o sólo funciona si usted presiona & mantener.

    Debe probar en un dispositivo real.

    Y no se olvide de establecer selectable.

    • No sé por qué esta respuesta está votado, porque veo el mismo comportamiento para este problema en el simulador y un dispositivo real.
  6. 1

    Si no hay ninguna razón apremiante para utilizar un UITextView, tales como que hay otro texto que se muestra, se puede utilizar un UILabel combinado con un UITapGestureRecognizer para conseguir el efecto que buscas.

    De lo contrario, usted podría ir con un real UIWebView lugar.

    • Yo estoy haciendo un montón de attributedString trabajo en el UITextView, así que prefiero esto a través de la construcción de una cadena HTML. También, necesito puntos específicos del texto seleccionable, no todo el texto para UILabel es demasiado.
    • Sí, pero es que no hay toque de relieve.
  7. 1

    Han tratado de establecer textview.delaysContentTouches = NO; ? Tal vez podría ayudar.

    • He – ese fue mi primer pensamiento, y se incluye en el código anterior. Sé que UITextView hereda de UIScrollView, así que pensé que estaba relacionado con que, de alguna manera.
    • ese fue mi primer instinto así. Me gustaría entonces recomendamos seguir adelante con su forma de trabajo a través de touchesBegan & es hermanos y attributesAtIndex y comprobar la NSLinkAttribute si es que existe.
    • ¿Cómo podría hacer esto? Esto suena como re-implementación de la detección de enlace…
    • También, ¿dónde está el attributesAtIndex método?
    • Sí, lo hace parecer así. El attributesAtIndex está disponible en el NSAttributedString de que UITextView. Me pueden enviar el código después de mañana

Dejar respuesta

Please enter your comment!
Please enter your name here