2009-05-14 15 views
18

पर स्विचिंग करते समय UITextView को कूदने से रोकें मुझे स्क्रॉलिंग UITextView में एक छोटी सी मात्रा को अपडेट करना होगा। मैं केवल एक चरित्र डालने वाला हूं जहां वर्तमान में कर्सर है, और मैं इसे अपने नेविगेशन बार पर एक बटन के प्रेस पर करूँगा।प्रोग्राम्सेटिक रूप से टेक्स्ट

मेरी समस्या यह है कि जब भी मैं टेक्स्ट व्यू की सेटटेक्स्ट विधि को कॉल करता हूं, तो यह टेक्स्ट के निचले भाग तक जाता है। मैंने सामग्री ऑफसेट का उपयोग करने और चयनित श्रेणी को रीसेट करने का प्रयास किया है लेकिन यह काम नहीं करता है! किसी भी तरह से तुम किसी भी पुस्तक आंदोलन ... के रूप में यदि वे सिर्फ कीबोर्ड पर कुछ टाइप किया था बिना पाठ अद्यतन कर सकते हैं वहाँ है

// Remember offset and selection 
CGPoint contentOffset = [entryTextView contentOffset]; 
NSRange selectedRange = [entryTextView selectedRange]; 
// Update text 
entryTextView.text = entryTextView.text; 
// Try and reset offset and selection 
[entryTextView setContentOffset:contentOffset animated:NO]; 
[entryTextView setSelectedRange: selectedRange]; 

: यहाँ मेरी उदाहरण है?

संपादित करें:

मैं textViewDidChange का उपयोग कर की कोशिश की है: विधि प्रतिनिधि लेकिन यह अभी भी मूल स्थान पर ऊपर स्क्रॉल नहीं है।

- (void)textViewDidChange:(UITextView *)textView { 
    if (self.programChanged) { 
     [textView setSelectedRange:self.selectedRange]; 
     [textView setContentOffset:self.contentOffset animated:NO]; 
     self.programChanged = NO; 
    } 
} 

- (void)changeButtonPressed:(id)sender { 
    // Remember position 
    self.programChanged = YES; 
    self.contentOffset = [entryTextView contentOffset]; 
    self.selectedRange = [entryTextView selectedRange]; 
    // Update text 
    entryTextView.text = entryTextView.text; 
} 

उत्तर

1

UITextViewDelegate पर एक नजर डालें, मेरा मानना ​​है कि textViewDidChangeSelection विधि आप क्या जरूरत है ऐसा करने की अनुमति हो सकती है।

+0

धन्यवाद जाँच की। इस प्रतिनिधि विधि में क्या होना चाहिए? क्या यह सामग्री की अंतिम रीसेटिंग ऑफ़सेट और चयनित श्रेणी होनी चाहिए? –

0

इतना सुंदर नहीं समाधान-लेकिन यह काम करता है तो कौन परवाह करता है:

- (IBAction)changeTextProgrammaticaly{ 
    myTextView.text = @"Some text"; 
    [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(rewindOffset) userInfo:nil repeats:NO]; 
} 

- (void)rewindOffset{ 
    [myTextView setContentOffset:CGPointMake(0,0) animated: NO]; 
} 
+0

(यह समाधान मेरे द्वारा काम नहीं किए गए सभी अन्य समाधानों के बाद आया था) – Tiger

+0

यह डाउनवोट के लायक नहीं है। कभी-कभी इन मुद्दों को स्क्रॉल करने के लिए रन लूप में हल किया जाना चाहिए। मुझे पता है कि और अधिक सुरुचिपूर्ण समाधान हो सकते हैं लेकिन यह काम करता है और हानिरहित है। – phatmann

14

आप iPhone 3.0 या बाद का उपयोग करते हैं, तो आप इस समस्या को हल कर सकते हैं:

textView.scrollEnabled = NO; 

//You should know where the cursor will be(if you update your text by appending/inserting/deleting you can know the selected range) so keep it in a NSRange variable. 

Then update text: 
textView.text = yourText; 

textView.scrollEnabled = YES; 
textView.selectedRange = range;//you keep before 

अब यह काम करना चाहिए (कोई अधिक कूद)

सादर मीर Assayag

+2

आईओएस 8 पर काम नहीं करता है। – Dmitry

2

सुझाए गए समाधानों में से कोई भी मेरे लिए काम नहीं करता है। -setContentOffset: एनिमेटेड: -setText द्वारा ट्रिगर किया जाता है: एनिमेटेड हाँ और सामग्री के साथ 3 बार अंत की ऑफसेट (एक UITextView के डिफ़ॉल्ट 8pt मार्जिन को घटाएं)। एक गार्ड में:

textView.contentOffsetAnimatedCallsDisabled = YES; 
textView.text = text; 
textView.contentOffsetAnimatedCallsDisabled = NO; 

-setContentOffset में एक UITextView उपवर्ग में: एनिमेटेड: मैं -setText लिपटे अपने अन्य तर्क के बीच

if (contentOffsetAnimatedCallsDisabled) return; // early return 

डाल दिया। सुपर कॉल मत भूलना। यह काम।

राफेल

+0

सुझाव के लिए धन्यवाद, मैं इसे आज़माउंगा! –

+1

यह निजी एपीआई नहीं है, आप UITextView को ओवरराइड करते हैं और मेरे उदाहरण के अनुसार व्यवहार को स्वयं लागू करते हैं। मेरे Assayag का जवाब मेरे मामले में और आईओएस 3.2 पर काम नहीं किया था। –

+0

आईओएस 7 पर यह काम नहीं करता है, क्योंकि सामग्री ऑफसेट विधि को प्रदर्शन समय पर फिर से बुलाया जाएगा। मैं एक कामकाजी समाधान की तलाश में हूं। – phatmann

8

बिल्डिंग मीर के सुझाव पर, यहाँ कोड है कि चयन प्रोग्राम के रूप में निकालता है (हाँ मैं जानता हूँ कि वहाँ एक चयन मेनू बटन है कि यह भी करता है, लेकिन मैं थोड़ा अजीब कुछ कर रहा हूँ) पाठ दृश्य स्क्रॉल किए बिना है ।

NSRange selectedRange = textView.selectedRange; 
textView.scrollEnabled = NO; 
// I'm deleting text. Replace this line with whatever insertions/changes you want 
textView.text = [textView.text 
       stringByReplacingCharactersInRange:selectedRange withString:@""]; 
selectedRange.length = 0; 
// If you're inserting text, you might want to increment selectedRange.location to be 
// after the text you inserted 
textView.selectedRange = selectedRange; 
textView.scrollEnabled = YES; 
+0

यह समाधान (चयनित श्रेणी को सेट करने के बाद स्क्रॉल सक्षम किया गया है, पहले नहीं) एक "जंपिंग टेक्स्ट" समस्या को ठीक किया गया था जब मैं UITextView की विशेषताकृत टेक्स्ट गुण सेट करते समय था! धन्यवाद –

+0

यह मेरी मदद नहीं करता है। – Dmitry

0

मुझे एक समाधान मिला जो आईओएस 6 और 7 (और शायद पहले के संस्करणों) में विश्वसनीय रूप से काम करता है।

@interface MyTextView() 
@property (nonatomic) BOOL needToResetScrollPosition; 
@end 

@implementation MyTextView 

- (void)setText:(NSString *)text 
{ 
    [super setText:text]; 
    self.needToResetScrollPosition = YES; 
} 

- (void)layoutSubviews 
{ 
    [super layoutSubviews]; 

    if (self.needToResetScrollPosition) { 
     self.contentOffset = CGPointMake(0, 0); 
     self.needToResetScrollPosition = NO; 
    } 
} 

अन्य उत्तर में से कोई भी आईओएस 7 में काम है क्योंकि यह प्रदर्शन समय में स्क्रॉल ऑफसेट समायोजित करेगा: UITextView का एक उपवर्ग में, निम्न करें।

+0

self.contentOffset हमेशा मेरे लिए 0,0 है (इस सबक्लास का आईओएस 7 के तहत स्क्रॉलिंग को रोकने पर कोई प्रभाव नहीं पड़ता है)। – Michael

1

पुराना सवाल लेकिन मुझे आईओएस 7 ऐप के साथ एक ही समस्या थी। सामग्री को बदलने की आवश्यकता है रन लूप के बाद थोड़ा सा ऑफसेट करें। यहां एक त्वरित विचार है।

self.clueString = [self.level clueText]; 
CGPoint point = self.clueText.contentOffset; 
self.clueText.attributedText = self.clueString; 
double delayInSeconds = 0.001; // after the run loop update 
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); 
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
    [self.clueText setContentOffset:point animated:NO]; 
}); 
2

आईओएस 7 में वहाँ sizeThatFits और अपने UITextView में होने लाइनब्रेक साथ एक बग समाधान मैंने पाया है कि काम करता है स्क्रॉल को अक्षम करके लपेट के लिए है होना करने के लिए तेजी। इस तरह:

textView.scrollEnabled = NO; 
CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)]; 
textView.scrollEnabled = YES; 

और अजीब कूद तय किया गया है।

+0

बड़ी सहायता। धन्यवाद! – JMarsh

+0

आईओएस 8 पर 'textView.scrollEnabled = NO'' textDidChange में: 'हमेशा के लिए स्क्रॉलिंग अक्षम करने लगता है। हालांकि इस ओएस पर यह 'viewDidLoad' के दौरान एक बार' scrollEnabled' को टॉगल करने के लिए पर्याप्त प्रतीत होता है, यानी इसे 'NO' पर सेट किया जाता है और सीधे' YES' –

4

निम्नलिखित दो समाधान आईओएस 8.0 पर मेरे लिए काम नहीं करते हैं।

textView.scrollEnabled = NO; 
[textView.setText: text]; 
textView.scrollEnabled = YES; 

और

CGPoint offset = textView.contentOffset; 
[textView.setText: text]; 
[textView setContentOffset:offset]; 

मैं सेटअप TextView के लिए एक प्रतिनिधि पुस्तक घटना पर नजर रखने, और पाया है कि मेरी आपरेशन बहाल करने के लिए के बाद ऑफसेट, ऑफसेट फिर 0 पर रीसेट हो जाता है। इसलिए मैं यह सुनिश्चित करने के लिए मुख्य ऑपरेशन कतार का उपयोग करता हूं कि "रीसेट टू 0" विकल्प के बाद मेरा पुनर्स्थापना ऑपरेशन होता है।

यहां मेरा समाधान है जो आईओएस 8.0 के लिए काम करता है।

CGPoint offset = self.textView.contentOffset; 
self.textView.attributedText = replace; 
[[NSOperationQueue mainQueue] addOperationWithBlock: ^{ 
    [self.textView setContentOffset: offset]; 
}]; 
+0

पर वापस चला जाता है, इसलिए सिम्युलेटर में इसका परीक्षण करते समय यह मेरी समस्या को ठीक करता था लेकिन किया मेरे डिवाइस पर चलते समय समस्या को ठीक न करें। इससे मुझे विश्वास होता है कि यह अभी भी दौड़ की स्थिति है। मैं केवल uitextview subclassing पर विचार कर रहा हूं और लेआउट प्रॉपर्टी सक्षम होने पर लेआउटब्यूव्यू विधि को ओवरराइड करने पर विचार कर रहा हूं। – Lobsterman

5

यह निर्णय iOS 8 के लिए काम करता है:

let offset = textView.contentOffset 
textView.text = newText 
textView.layoutIfNeeded() 
textView.setContentOffset(offset, animated: false) 

यह कॉल करने के लिए वास्तव में setContentOffset:animated: क्योंकि केवल इस एनीमेशन रद्द हो जाएगा आवश्यक है। textView.contentOffset = offset एनीमेशन रद्द नहीं करेगा और मदद नहीं करेगा।

3

आदेश में एक UITextView का पाठ संपादित करने के लिए, आप इसे textStorage क्षेत्र है अद्यतन करने की आवश्यकता:

[_textView.textStorage beginEditing]; 

NSRange replace = NSMakeRange(10, 2); //enter your editing range 
[_textView.textStorage replaceCharactersInRange:replace withString:@"ha ha$ "]; 

//if you want to edit the attributes 
NSRange attributeRange = NSMakeRange(10, 5); //enter your editing attribute range 
[_textView.textStorage addAttribute:NSBackgroundColorAttributeName value:[UIColor greenColor] range:attributeRange]; 

[_textView.textStorage endEditing]; 

गुड लक

1

मैं IOS9 में एक समान, अगर नहीं एक ही है, समस्या मारा। कुछ पाठ की विशेषताओं को बदलने के लिए, कहें, बोल्ड दृश्य को चयन से बाहर स्क्रॉल करने के लिए दृश्य का कारण बनता है। मैं setSelectedRange के बाद scrollRangeToVisible के लिए एक कॉल जोड़कर इस अनुसार क्रमबद्ध:

[self setSelectedRange:range]; 
    [self scrollRangeToVisible:range]; 
+0

पूरी तरह से कोई समझदार कूद और इतना आसान के साथ काम करता है! मुझे नहीं पता कि मुझे यह कैसे याद आया! – siburb

1

अंत में यह कोशिश करते हैं, आपके इनपुट के लिए आईओएस 10 पर

let offset = textView.contentOffset 
textView.attributedText = newValue 
OperationQueue.main.addOperation { 
    self.textView.setContentOffset(offset, animated: false) 
} 
संबंधित मुद्दे