2017-01-11 18 views
1

私は実際にQuranアプリケーションを開発していますが、TextKitを使用して句を強調表示し、色を変更しています。すべてがうまくいっていますが、私は複数回出現する言葉に少し問題があります。まず第一に、私のコードは次のとおりです。TextKitで重複した単語を選択して強調表示する

import UIKit 

class ViewController: UIViewController { 

    let attributedBackgroundColor = [ NSBackgroundColorAttributeName: UIColor.lightGray ] 
    var myVerses = ["بِسْمِ اللَّهِ الرَّحْمَنِ الرَّحِيمِ","الْحَمْدُ لِلَّهِ رَبِّ الْعَالَمِينَ","الرَّحْمَنِ الرَّحِيمِ","مَالِكِ يَوْمِ الدِّينِ","إِيَّاكَ نَعْبُدُ وَإِيَّاكَ نَسْتَعِينُ","اهدِنَا الصِّرَاطَ الْمُسْتَقِيمَ","صِرَاطَ الَّذِينَ أَنْعَمْتَ عَلَيْهِمْ غَيْرِ الْمَغْضُوبِ عَلَيْهِمْ وَلاَ الضَّالِّينَ"] 

    @IBOutlet weak var textView: UITextView! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     let string = NSMutableAttributedString(string: "Vide initialement") 
     string.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize: CGFloat(25.0)), range: NSRange(location: 0, length: string.length)) 
     let paragraphStyle = NSMutableParagraphStyle() 
     paragraphStyle.alignment = .center 
     string.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: NSRange(location: 0, length: string.length)) 

     textView.attributedText = string 
     let singleTap = UITapGestureRecognizer(target: self, action: #selector(ViewController.tapRecognized)) 
     singleTap.numberOfTapsRequired = 1 
     textView.addGestureRecognizer(singleTap) 
     textView.isEditable = false 
     textView.isSelectable = false 

     var str = "" 

// Ajouter numérotation aux verses - Add numerotation to verses. 
     for i in 0..<myVerses.count { 
      if i > 0 { 
       str += "("+"\(i)"+")" 
      } 
      str += String(myVerses[i]) 
     } 
     print(str) 
     textView.text = str + "("+"\(myVerses.count)"+")" 
    } 
    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 


    // Sélection des verses - Select Verses 
    func tapRecognized(_ recognizer: UITapGestureRecognizer) { 
     if recognizer.state == .recognized { 
      let point = recognizer.location(in: recognizer.view) 
      let detectedText = self.getWordAtPosition(pos: point, in: textView) 
      if (detectedText != "") { 
       print("detectedText == \(detectedText)") 
       let string = NSMutableAttributedString(string: self.textView.text) 
       let verses = self.textView.text.components(separatedBy: ")") 



       if let detectedRange = textView.text.range(of: detectedText) { 
        let startPosOfSubstring = textView.text.distance(from: textView.text.startIndex, to: detectedRange.lowerBound) 
        let detectedLength = detectedText.characters.count 
       let rangeOfSub = (startPosOfSubstring,detectedLength) 
       print("-- rangeofSub == " ,rangeOfSub) 
        let rangeOfSubstring = NSRange(location: startPosOfSubstring, length: detectedLength) 


        for verse: String in verses { 
         if let detectedVerse = textView.text.range(of: verse) { 
          let startPosOfVerse = textView.text.distance(from: textView.text.startIndex, to: detectedVerse.lowerBound) 
          let detectedLengthOfVerse = verse.characters.count 

          let tupleVerse = (startPosOfVerse,detectedLengthOfVerse) 
          print("++ rangeofVerse == " ,tupleVerse) 
          let rangeOfVerse = NSRange(location: startPosOfVerse, length: detectedLengthOfVerse) 
          print(verse) 


          let range = (self.textView.text as NSString).range(of: verse) 
          let contained = NSLocationInRange(rangeOfSubstring.location, rangeOfVerse) 
          if (contained) { 
           print ("************************************") 
          print("contained is :" ,contained) 
           print ("************************************") 

           string.addAttribute(NSForegroundColorAttributeName, value: UIColor.red, range: range) 
           string.addAttribute(NSBackgroundColorAttributeName, value: UIColor.darkGray, range: range) 
           string.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize: CGFloat(25.0)), range: NSRange(location: 0, length: string.length)) 
           let paragraphStyle = NSMutableParagraphStyle() 
           paragraphStyle.alignment = .center 
           string.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: NSRange(location: 0, length: string.length)) 

          } 
          print ("--------------------------------------------") 

         } 

        } 
        self.textView.attributedText = string 
       } else { 
        print("detectedText is empty") 
       } 
      } 
     } 
    } 



    func getWordAtPosition(pos: CGPoint, in textview: UITextView) -> String { 
     //Eleminer le balancement du scroll - eliminate scroll offset 
    // var pos = pos 
    // pos.y += tv.contentOffset.y 
     //Position du text tapé au point - get location in text from textposition at point 
     let tapPos = textview.closestPosition(to: pos) 
     //Avoir le mot tapé dans la position du point - fetch the word at this position (or nil, if not available) 
     if let wr = textview.tokenizer.rangeEnclosingPosition(tapPos!, with: .word, inDirection: UITextLayoutDirection.right.rawValue) { 
      print(pos) 
      return textview.text(in: wr)! 
     }else{ 
      return "" 
     } 

    } 
} 

私はシミュレータ上で私のアプリを実行すると、私は詩を選択して、それは素晴らしいだろう。

通常の使用:

Normal Use

問題が複数回表示される言葉です。たとえば、最初の単語か2番目の単語かにかかわらず、2回見つけた単語 "رحمن"では、強調表示される詩は常に最初のものになります。

Problem

私が間違って何をしているのですか? ありがとうございます。

+0

'範囲を'唯一の最初の試合を返します。あなたはそれを行うためにループするか、すべての出現を見つけるNSRegularExpressionを使用する必要があります... – Larme

+0

ループとはどういう意味ですか?私はすべてのtextViewテキストを取り出しました –

+0

@Larmeあなたは助けてくださいできますか? –

答えて

0

私はあなたの質問を理解しているので、ユーザーがその詩の中の特定の単語を選択すると、詩全体がハイライトされます。

ロジックの問題は、ユーザーが選択した単語を決定することですが、その単語は必ずしも一意ではないため、この単語(textView.text.range(of: detectedText))を検索すると最初の結果が返されます。ユーザーが実際に選択したものではない可能性があります。

解決策の1つは、トークナイザがテキストを正しく理解している場合、ユーザーの選択を決定するときに別のTextGranularityを使用することです。代わりに:

textview.tokenizer.rangeEnclosingPosition(tapPos!, with: .word, inDirection: UITextLayoutDirection.right.rawValue) 

あなたは試みることができる:(の:)

textview.tokenizer.rangeEnclosingPosition(tapPos!, with: .sentence, inDirection: UITextLayoutDirection.right.rawValue) 
+0

ナア男、私はそれを試みたが、それはdoes notは物事を行う。 thnx –

+0

「それは何もしません」とはどういう意味ですか?あなたのアプリのふるまいはすべてそれを変えますか?エラーメッセージはありますか?もっと情報が必要です。 –

+0

アプリの動作は同じです –

関連する問題