2015-12-22 12 views
12

Sto tentando di visualizzare una stringa attribuita in una UITextview con collegamenti cliccabili. Ho creato un semplice progetto di test per vedere dove sto andando male e ancora non riesco a capirlo. Ho provato a abilitare l'interazione dell'utente e impostare il metodo delegato shouldInteractWithURLs, ma non funziona ancora. Ecco il mio codice (per un controller della vista che contiene solo un TextView)Come visualizzare i collegamenti selezionabili in UITextView

@IBOutlet weak var textView: UITextView! 

override func viewDidLoad() { 
    super.viewDidLoad() 
    // Do any additional setup after loading the view, typically from a nib. 
    let string = "Google" 
    let linkString = NSMutableAttributedString(string: string) 
    linkString.addAttribute(NSLinkAttributeName, value: NSURL(string: "https://www.google.com")!, range: NSMakeRange(0, string.characters.count)) 
    linkString.addAttribute(NSFontAttributeName, value: UIFont(name: "HelveticaNeue", size: 25.0)!, range: NSMakeRange(0, string.characters.count)) 
    textView.attributedText = linkString 
    textView.delegate = self 
    textView.selectable = true 
    textView.userInteractionEnabled = true 
} 

Ed ecco i metodi delegato Ho implementato:

func textViewShouldBeginEditing(textView: UITextView) -> Bool { 
    return false 
} 

func textView(textView: UITextView, shouldInteractWithURL URL: NSURL, inRange characterRange: NSRange) -> Bool { 
    return true 
} 

Questo ancora non funziona. Ho cercato su questo argomento e nulla è stato ancora aiutato. Grazie mille in anticipo.

risposta

34

Basta selezionare lo UITextView nello storyboard e andare a "Mostra ispettore attributi" e selezionare selectable e links. Come mostra l'immagine qui sotto. Assicurati che Editable sia deselezionato.

enter image description here

+1

Grazie. In realtà l'ho appena scoperto subito dopo la pubblicazione (dopo aver trascorso diverse ore su questo già, vai a capire). Avevo già selezionato i collegamenti e selezionabili, ma avevo bisogno di deselezionare "Modificabile" per farlo funzionare. – jhk727

+1

Rashwan, cosa succede se voglio rendere modificabile la vista del testo ma voglio anche il rilevamento automatico del link quando la vista testuale si dimette come primo risponditore, come nell'app iOS Notes? Posso farlo? – owlswipe

+0

C'è un modo per farlo con modificabile? –

1

Swift 3 iOS 10: Ecco cliccabile UITextView estesa che rilevano i siti web all'interno del TextView automaticamente finché il legame iniziare con www. ad esempio: www.exmaple.com se esiste in qualsiasi parte del testo sarà selezionabile. Ecco la classe:

import Foundation 
import UIKit 




public class ClickableTextView:UITextView{ 



    var tap:UITapGestureRecognizer! 
    override public init(frame: CGRect, textContainer: NSTextContainer?) { 
     super.init(frame: frame, textContainer: textContainer) 
     print("init") 
     setup() 
    } 
    required public init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     setup() 
    } 


    func setup(){ 

     // Add tap gesture recognizer to Text View 
     tap = UITapGestureRecognizer(target: self, action: #selector(self.myMethodToHandleTap(sender:))) 
     //  tap.delegate = self 
     self.addGestureRecognizer(tap) 
    } 

    func myMethodToHandleTap(sender: UITapGestureRecognizer){ 

     let myTextView = sender.view as! UITextView 
     let layoutManager = myTextView.layoutManager 

     // location of tap in myTextView coordinates and taking the inset into account 
     var location = sender.location(in: myTextView) 
     location.x -= myTextView.textContainerInset.left; 
     location.y -= myTextView.textContainerInset.top; 


     // character index at tap location 
     let characterIndex = layoutManager.characterIndex(for: location, in: myTextView.textContainer, fractionOfDistanceBetweenInsertionPoints: nil) 

     // if index is valid then do something. 
     if characterIndex < myTextView.textStorage.length { 

      let orgString = myTextView.attributedText.string 


      //Find the WWW 
      var didFind = false 
      var count:Int = characterIndex 
      while(count > 2 && didFind == false){ 

       let myRange = NSRange(location: count-1, length: 2) 
       let substring = (orgString as NSString).substring(with: myRange) 

//    print(substring,count) 

       if substring == " w" || (substring == "w." && count == 3){ 
        didFind = true 
//     print("Did find",count) 

        var count2 = count 
        while(count2 < orgString.characters.count){ 

         let myRange = NSRange(location: count2 - 1, length: 2) 
         let substring = (orgString as NSString).substring(with: myRange) 

//      print("Did 2",count2,substring) 
         count2 += 1 


         //If it was at the end of textView 
         if count2 == orgString.characters.count { 

          let length = orgString.characters.count - count 
          let myRange = NSRange(location: count, length: length) 

          let substring = (orgString as NSString).substring(with: myRange) 

          openLink(link: substring) 
          print("It's a Link",substring) 
          return 
         } 

         //If it's in the middle 

         if substring.hasSuffix(" "){ 

          let length = count2 - count 
          let myRange = NSRange(location: count, length: length) 

          let substring = (orgString as NSString).substring(with: myRange) 

          openLink(link: substring) 
          print("It's a Link",substring) 

          return 
         } 

        } 

        return 
       } 


       if substring.hasPrefix(" "){ 

        print("Not a link") 
        return 
       } 

       count -= 1 

      } 


     } 


    } 


    func openLink(link:String){ 

     if let checkURL = URL(string: "http://\(link.replacingOccurrences(of: " ", with: ""))") { 
      if UIApplication.shared.canOpenURL(checkURL) { 
       UIApplication.shared.open(checkURL, options: [:], completionHandler: nil) 

       print("url successfully opened") 
      } 
     } else { 
      print("invalid url") 
     } 
    } 


    public override func didMoveToWindow() { 
     if self.window == nil{ 
      self.removeGestureRecognizer(tap) 
      print("ClickableTextView View removed from") 
     } 
    } 
} 
+0

non sarebbe meglio sostituire i caratteri di spaziatura con i caratteri di escape '% 20'? – royalmurder

Problemi correlati