2017-01-11 8 views
1

저는 실제로 TextKit을 사용하여 구절을 강조하고 색상을 변경하는 Quran 응용 프로그램을 개발하고 있습니다. 모든 것이 잘되고 있지만 여러 번 나타나는 단어에는 약간의 문제가 있습니다. 우선, 내 코드는 다음과 같습니다.반복되는 단어의 잘못된 발생을 선택하여 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

문제는 한 번 이상 나타날 단어입니다. 예를 들어 첫 번째 단어 나 두 번째 단어를 선택했는지 여부에 관계없이 두 번 발견되는 "الرحمن"단어의 경우 강조 표시된 절이 항상 첫 번째 단어입니다. 내가 잘못 뭐하는 거지

Problem

? 미리 감사드립니다.

+0

'범위'첫 번째 일치를 반환합니다. 당신은 그것을하기 위해 반복하거나, 모든 발생을 찾는 NSRegularExpression을 사용해야합니다 ... – Larme

+0

루프로 무엇을 의미합니까? 모든 textView 텍스트를 가져 왔습니다. –

+0

@Larme 제발 도와 드릴까요? –

답변

0

내가 알기로는, 사용자가 그 절에서 특정 단어를 선택할 때 전체 절을 강조하고 싶습니다.

논리의 문제는 사용자가 선택한 단어를 결정하지만이 단어가 반드시 고유하지는 않으므로이 단어 (textView.text.range(of: detectedText))를 검색하면 첫 번째 결과가 나타납니다. 또는 사용자가 실제로 선택한 것일 수 없습니다.

잠재적 해결책 중 하나는 사용자가 텍스트를 올바르게 이해하고있는 경우 사용자의 선택을 결정할 때 다른 TextGranularity을 사용하는 것입니다. 대신에 :

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

당신이 시도 할 수 : (의 :)

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

Naa man, 나는 그것을 시도했다. 그러나 does not는 물건을한다. thnx –

+0

"그 일을하지 않는다"는 것은 무엇을 의미합니까? 앱의 동작이이 모든 것을 변경합니까? 오류 메시지가 있습니까? 우리는 더 많은 정보가 필요합니다. –

+0

앱의 동작은 여전히 ​​동일합니다. –