2016-04-16 12 views
0

ユーザーがテキストの特定のポイントに到達したときを検出しようとしています.UITextViewの中の文字列。私はscrollViewDidEndDraggingを使用していますが、結果は理想的ではありません。私がスクロールを終えると、スクロールする必要があります。また、テキストが1ページだけの場合、このメソッドは呼び出されません。最後の行(または他の行)が画面に表示されているときにわかりやすい方法がありますか? あなたがSwiftのUITextViewテキストの終わり

func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) { 
     let bottomEdge: CGFloat = textField.contentOffset.y + textField.frame.size.height 
     if (bottomEdge >= scrollView.contentSize.height) { 
      //do stuff 
     } 
    } 

答えて

0

ここではその矩形を表示するかどうかのサブストリングのRECTや小切手を取得素朴なソリューションですありがとうございました。

この実装の主な欠点は、部分文字列が一意である場合(最初のオカレンスのみを取得するため)にのみ機能することです。しかし、それは実装するにはあまりにも悪いはずはありません(おそらくあなたがチェックするrectの配列で)。

UITextViewヘルパー

私は便宜上UITextViewの拡張子を作成しました。 2つの方法があります:部分文字列の矩形を決定する方法と、その矩形が可視かどうかを調べる方法です。

rectForTextは、主にRange<Index>からUITextRangeへの変換が予想よりも痛いことが判明しているため、非常に冗長です。誰かが簡単な方法を知っていれば、分かち合いましょう。

extension UITextView { 
    func rectForText(targetText: String) -> CGRect? { 
     if let range = text.rangeOfString(targetText) { 
      let beginning = beginningOfDocument 
      let startOffset = text.startIndex.distanceTo(range.startIndex) 
      if let start = positionFromPosition(beginning, offset: startOffset) { 
       let endOffset = text.startIndex.distanceTo(range.endIndex) - startOffset 
       if let end = positionFromPosition(start, offset: endOffset) { 
        if let textRange = textRangeFromPosition(start, toPosition: end) { 
         return firstRectForRange(textRange) 
        } 
       } 
      } 
     } 

     return nil 
    } 

    func isRectVisible(rect: CGRect?) -> Bool { 
     if let rect = rect { 
      return CGRectIntersectsRect(rect, bounds) 
     } 

     return false 
    } 
} 

テストコード

最後に、私は、単一のテキストビューとビューコントローラを持っている簡単なテストプロジェクトを作成しました。ビューが表示されたら表示を確認し、次にスクロールビューがスクロールすると表示を確認します。私はまた、あなたがスクロールするたびにそれを再計算するのを避けるために、テストレットをキャッシュしました。しかし、テキストが動的な場合は、これを再計算する必要があります。

class ViewController: UIViewController, UITextViewDelegate { 
    @IBOutlet weak var myTextView: UITextView! 
    var rectOfString: CGRect? 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     myTextView.delegate = self 
     myTextView.text = "foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar My cool substring foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar " 
     rectOfString = myTextView.rectForText("My cool substring") 
    } 

    override func viewDidAppear(animated: Bool) { 
     super.viewDidAppear(animated) 

     checkTextVisibility() 
    } 

    private func checkTextVisibility() { 
     if myTextView.isRectVisible(rectOfString) { 
      print("Visible :)") 
     } else { 
      print("Not visible :(") 
     } 
    } 
} 

extension ViewController: UIScrollViewDelegate { 
    func scrollViewDidScroll(scrollView: UIScrollView) { 
     checkTextVisibility() 
    } 
} 
+0

私の解決策と同じ... – PoolHallJunkie

+0

@PoolHallJunkieねえ、あなたの答えは完全ではありません。私は今私がテストした解決策で私の答えを完全に書き直しました。うまくいけば、これはより良い解決策です。 – nebs

関連する問題