저는 실제로 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 ""
}
}
}
시뮬레이터에서 앱을 실행할 때 구절을 선택하면 훌륭합니다.
일반 사용 :
문제는 한 번 이상 나타날 단어입니다. 예를 들어 첫 번째 단어 나 두 번째 단어를 선택했는지 여부에 관계없이 두 번 발견되는 "الرحمن"단어의 경우 강조 표시된 절이 항상 첫 번째 단어입니다. 내가 잘못 뭐하는 거지
? 미리 감사드립니다.
'범위'첫 번째 일치를 반환합니다. 당신은 그것을하기 위해 반복하거나, 모든 발생을 찾는 NSRegularExpression을 사용해야합니다 ... – Larme
루프로 무엇을 의미합니까? 모든 textView 텍스트를 가져 왔습니다. –
@Larme 제발 도와 드릴까요? –