2012-02-14 14 views
10

मेरा लक्ष्य UITextView में सभी दृश्यमान गलत वर्तनी वाले शब्दों को चिह्नित करना है।UITextView में दृश्यमान शब्दों के लिए CGRects को कुशलता से कैसे ढूंढें?

अक्षम एल्गोरिदम टेक्स्ट में गलत वर्तनी वाले शब्दों की सभी श्रेणियों को खोजने के लिए वर्तनी परीक्षक का उपयोग करना है, उन्हें स्थिति का उपयोग करके UITextRange ऑब्जेक्ट्स में कनवर्ट करें: स्थिति: इनडिरेक्शन: ऑफ़सेट इत्यादि, फिर UITextInput विधि का उपयोग करके ग्राफिक्स रीक्ट्स प्राप्त करें पहले RectFromRange।

इस प्रकार सभी पाठ -> गलत वर्तनी शब्दों> NSRange संग्रह -> UITextRange संग्रह -> CGRect संग्रह -> दृश्यता के लिए मूल्यांकन, दृश्य लोगों

समस्या आकर्षित यह जरूरी है कि कि सभी पाठ को चेक किया गया है, और सभी गलत वर्तनी वाले शब्दों को ग्राफिक्स रीक्ट में परिवर्तित कर दिया जाता है।

इस प्रकार, मैं कल्पना जाने का रास्ता किसी भी तरह UITextView उस पल में दिखाई दे रहा है में अंतर्निहित .text किस भागों पता लगाने के लिए है।

इस प्रकार पाठ दर्शनीय की श्रेणी के लिए -> गलत वर्तनी शब्दों> NSRange संग्रह -> UITextRange संग्रह -> CGRect संग्रह -, दृश्यता के लिए मूल्यांकन> दिखाई लोगों

आकर्षित ios - how to find what is the visible range of text in UITextView? में कोड बाध्य के लिए एक रास्ता के रूप में काम कर सकते हैं टेक्स्ट के किस हिस्से को जांचने के लिए, लेकिन अभी भी यह आवश्यक है कि सभी टेक्स्ट मापा जाए, जो मुझे लगता है कि काफी महंगा हो सकता है।

कोई सुझाव?

उत्तर

18

UITextView के बाद से UIScrollView का एक उपवर्ग है, इसका bounds संपत्ति अपने समन्वय प्रणाली के दृश्य भाग को दर्शाता है। तो कुछ इस तरह काम करना चाहिए:

- (NSRange)visibleRangeOfTextView:(UITextView *)textView { 
    CGRect bounds = textView.bounds; 
    UITextPosition *start = [textView characterRangeAtPoint:bounds.origin].start; 
    UITextPosition *end = [textView characterRangeAtPoint:CGPointMake(CGRectGetMaxX(bounds), CGRectGetMaxY(bounds))].end; 
    return NSMakeRange([textView offsetFromPosition:textView.beginningOfDocument toPosition:start], 
     [textView offsetFromPosition:start toPosition:end]); 
} 

यह एक ऊपर से नीचे, बाएं से दाएं पाठ लेआउट मान लिया गया है। यदि आप इसे अन्य लेआउट दिशाओं के लिए काम करना चाहते हैं, तो आपको कड़ी मेहनत करनी होगी। :)

+0

अच्छा लगा। दक्षता के लिए, शुरुआत से आगे के अक्षरों को आगे बढ़ाकर अंत खोजें - यह पता चला है कि यह दस्तावेज़ में शुरुआत से सभी तरह से धीमा हो रहा है, लेकिन अग्रिम करने के लिए सस्ता है। –

+0

जब आप कहते हैं, "ऐसा कुछ काम करना चाहिए", क्या आपने वास्तव में इसे आजमाया है? यह मेरे लिए वास्तविक दृश्य पाठ की लगभग तीन गुना वापसी कर रहा है। धन्यवाद। –

+1

@ जेसनटाइलर [यहां एक रेपो है जिसमें एक परीक्षण ऐप है।] (Https://github.com/mayoff/textview-visible-range) मेरे लिए बहुत अच्छा काम करता है। शायद Xcode 6 की आवश्यकता है। –

3

स्विफ्ट में लिखा रॉब का जवाब। मैंने कुछ सुरक्षा जांच जोड़े हैं।

private func visibleRangeOfTextView(textView: UITextView) -> NSRange { 
    let bounds = textView.bounds 
    let origin = CGPointMake(10,10) //Overcome the default UITextView left/top margin 
    let startCharacterRange = textView.characterRangeAtPoint(origin) 
    if startCharacterRange == nil { 
     return NSMakeRange(0,0) 
    } 
    let startPosition = textView.characterRangeAtPoint(origin)!.start 

    let endCharacterRange = textView.characterRangeAtPoint(CGPointMake(CGRectGetMaxX(bounds), CGRectGetMaxY(bounds))) 
    if endCharacterRange == nil { 
     return NSMakeRange(0,0) 
    } 
    let endPosition = textView.characterRangeAtPoint(CGPointMake(CGRectGetMaxX(bounds), CGRectGetMaxY(bounds)))!.end 

    let startIndex = textView.offsetFromPosition(textView.beginningOfDocument, toPosition: startPosition) 
    let endIndex = textView.offsetFromPosition(startPosition, toPosition: endPosition) 
    return NSMakeRange(startIndex, endIndex) 
} 

स्विफ्ट 4 के लिए अपडेट किया गया:

private func visibleRangeOfTextView(textView: UITextView) -> NSRange { 
    let bounds = textView.bounds 
    let origin = CGPoint(x: 10, y: 10) //Overcome the default UITextView left/top margin 
    let startCharacterRange = textView.characterRange(at: origin) 
    if startCharacterRange == nil { 
     return NSRange(location: 0, length: 0) 
    } 
    let startPosition = textView.characterRange(at: origin)?.start 

    let endCharacterRange = textView.characterRange(at: CGPoint(x: bounds.maxX, y: bounds.maxY)) 
    if endCharacterRange == nil { 
     return NSRange(location: 0, length: 0) 
    } 
    let endPosition = textView.characterRange(at: CGPoint(x: bounds.maxX, y: bounds.maxY))!.end 

    let startIndex = textView.offset(from: textView.beginningOfDocument, to: startPosition!) 
    let endIndex = textView.offset(from: startPosition!, to: endPosition) 
    return NSRange(location: startIndex, length: endIndex) 
} 

उदाहरण उपयोग, एक बटन नल से कहा जाता है:

@IBAction func buttonTapped(sender: AnyObject) { 
    let range = visibleRangeOfTextView(self.textView) 

    // Note: "as NSString" won't work correctly with Emoji and stuff, 
    // see also: http://stackoverflow.com/a/24045156/1085556 
    let nsText = self.textView.text as NSString 
    let text = nsText.substringWithRange(range) 
    NSLog("range: \(range), text = \(text)")   
} 
संबंधित मुद्दे