2015-12-22 14 views
12

クリック可能なリンクを持つUITextviewに属性付きの文字列を表示しようとしています。私はどこに間違っているのかを知るための簡単なテストプロジェクトを作成しましたが、それはまだ分かりません。私はユーザーインタラクションを有効にし、shouldInteractWithURLsデリゲートメソッドを設定しようとしましたが、まだ動作していません。UITextViewでクリック可能なリンクを表示する方法

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

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

これはまだ機能していません。ここに私のコードは

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

そして、ここでは、私が実装しましたデリゲートメソッドです(唯一のTextViewを含むビューコントローラ用)です。私はこのトピックを検索しましたが、まだ何も助けていません。事前にありがとうございます。

答えて

34

あなたのストーリーボードでUITextViewを選択し、「属性の表示」に移動し、selectablelinksを選択します。下のイメージが示すように。 Editableがオフになっていることを確認してください。

enter image description here

+1

ありがとうございます。私は実際にポストした直後にそれを理解しました(これに数時間を費やしてから、図に行く)。私は既に選択可能なリンクをチェックしていましたが、動作させるには "編集可能"のチェックを外す必要がありました。 – jhk727

+1

Rashwan、テキストビューを編集可能にしたいが、iOS Notesアプリのように、テキストビューが最初のレスポンダを辞退したときに自動リンク検出をしたい場合はどうすればよいですか?それをしてもいいですか? – owlswipe

+0

編集可能な状態でこれを行う方法はありますか? –

1

スウィフト3 iOSの10:はここWWWで始まるリンクとして自動的限りのTextView内のウェブサイトを検出クリッカブル拡張UITextViewです。の場合:www.exmaple.comテキストのどこにでも存在する場合はクリック可能です。クラスは次のとおりです。

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

空白文字を '%20'エスケープ文字に置き換えるほうがよいでしょうか? – royalmurder

関連する問題