2012-06-26 21 views
5

मेरे पास UITextView का उप-वर्ग है और मैं इसे अपने स्वयं के प्रतिनिधि बनाना चाहता हूं। ताकि मैं textView:shouldChangeTextInRange:replacementText: विधि को ओवरराइड कर सकूं, और लगातार रिक्त स्थान दर्ज कर सकूं।UITextView अपने प्रतिनिधि के रूप में है अनंत अनंत लूप

[SATextView awakeFromNib] में (SATextView UITextView का मेरा सबक्लास है), मैं [self setDelegate:self]; करता हूं। जब मैं सब कुछ फ्रीज संपादित करने के लिए टेक्स्टव्यू पर दबाता हूं और अंततः बंद हो जाता है, और उस बैकट्रैक से पता चलता है कि एक अनंत लूप रहा है।

इससे कोई फर्क नहीं पड़ता कि मैं सभी प्रतिनिधि तरीकों को लागू करता हूं, केवल एक या कोई नहीं। इससे कोई फर्क नहीं पड़ता कि क्या वे विधियां खाली हैं।

इसका कारण अनंत लूप क्यों होता है? ऐसा लगता है कि यदि UITextView (अन्य ऑब्जेक्ट्स आप subclass और प्रतिनिधि को स्वयं को सेट कर सकते हैं, और इसमें यह समस्या नहीं होगी)। और मैं इसे कैसे रोक सकता हूं? या क्या इस सबक्लास को लगातार रिक्त स्थान प्राप्त करने में कोई बेहतर तरीका नहीं है,

+0

इसके बारे में सोचें। कठिन। एक वर्ग होना अपना प्रतिनिधि होना संभव है, लेकिन इसके लिए विचार की आवश्यकता है। –

+0

@ हॉटलिक्स मेरे पास इसके बारे में है, मैंने इसे बिना किसी समस्या के अन्य कक्षाओं के साथ किया है? क्या आप मदद कर सकते हैं? –

+0

बैकट्रैक आपको उस लूप को दिखाना चाहिए जिसमें आप हैं। –

उत्तर

1

एक विचार ... आप एक प्रतिनिधि वर्ग बना सकते हैं जो असली प्रतिनिधि और UITextView के बीच मध्य व्यक्ति के रूप में कार्य करता है (क्योंकि आप करेंगे शायद कुछ समय बाद प्रतिनिधि को सेट करने की जरूरत है)। तो यह नई कक्षा प्रतिनिधि प्रोटोकॉल को कार्यान्वित करेगी, लेकिन इसके पास अपने स्वयं के प्रतिनिधि के लिए एक संपत्ति भी होगी, ताकि आप टेक्स्ट व्यू को आगे बढ़ा सकें: mustChangeTextInRange: replacementText :, और अभी भी अपने मध्य में कक्षाओं को संपादित करने का काम कर सकते हैं।

+0

कहा जाना चाहिए जो मैं अनुशंसा करता हूं। एक सहायक वर्ग बनाएं जो 'UITextViewDelegate' लागू करता है और आपके इच्छित व्यवहारों को लागू करता है। समग्र तर्क का प्रबंधन करने वाले नियंत्रक को संदेश भेजने के लिए वांछित होने पर इस वर्ग का अपना प्रोटोकॉल हो सकता है। यह पैटर्न कई परिदृश्यों में उपयोगी है, मैं इसे 'UITableViewDataSource' के लिए भी उपयोग करता हूं। आप अच्छे, साफ, पुन: प्रयोज्य प्रोटोकॉल कार्यान्वयन के साथ समाप्त होते हैं। – XJones

0

किसी ऑब्जेक्ट में पर्यवेक्षकों की किसी भी संख्या की सदस्यता लेना संभव है। इसलिए स्वयं सदस्यता लेना संभव है:

@implementation MyTextView 

-(id) initWithFrame:(CGRect)frame // or initWithCoder: for loading from nib 
{ 
    self = [super initWithFrame:frame]; 
    if(self) { 
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textViewTextDidChangeNotification:) name:UITextViewTextDidChangeNotification object:self]; 
    } 
    return self; 
} 

-(void)textViewTextDidChangeNotification:(NSNotification*)n 
{ 
    self.text = [self.text stringByReplacingOccurrencesOfString:@" " withString:@" "]; 
} 
+1

धन्यवाद, लेकिन मुझे 'चाहिए' विधियों की आवश्यकता है जिसे अधिसूचना केंद्र का उपयोग करके देखा नहीं जा सकता –

0

यहां एक उदाहरण दिया गया है कि मैंने इसे सफलतापूर्वक कैसे किया है। मैं केवल कुछ वर्णों को इनपुट होने से रोकने में रूचि रखता था इसलिए मैं केवल textView:shouldChangeTextInRange:replacementText: लागू करता हूं और फिर बाकी को पास करता हूं।

#import "INFTextView.h" 

@interface INFTextView() <UITextViewDelegate> 

@property (nonatomic, weak) id<UITextViewDelegate> externalDelegate; 

@end 

@implementation INFTextView 

- (id)init { 
    self = [super init]; 
    if (!self) { 
     return nil; 
    } 

    self.delegate = self; 

    return self; 
} 

- (void)awakeFromNib { 
    self.delegate = self; 
} 

- (void)setDelegate:(id<UITextViewDelegate>)delegate { 
    // we always want self to be the delegate, if someone is interested in delegate calls we will forward those on if applicable 
    if (delegate == self) { 
     [super setDelegate:self]; 
     return; 
    } else { 
     // capture that someone else is interested in delegate calls 
     _externalDelegate = delegate; 
    } 
} 

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { 
    NSCharacterSet *unsupportedCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:kINFSupportedCharacters] invertedSet]; 

    NSRange unsupportedCharacterRange = [text rangeOfCharacterFromSet:unsupportedCharacterSet]; 
    if (unsupportedCharacterRange.location == NSNotFound) { 
     return YES; 
    } else { 
     return NO; 
    } 
} 

- (BOOL)textViewShouldBeginEditing:(UITextView *)textView { 
    if ([_externalDelegate respondsToSelector:@selector(textViewShouldBeginEditing:)]) { 
     return [_externalDelegate textViewShouldBeginEditing:textView]; 
    } 

    return YES; 
} 

- (BOOL)textViewShouldEndEditing:(UITextView *)textView { 
    if ([_externalDelegate respondsToSelector:@selector(textViewShouldEndEditing:)]) { 
     return [_externalDelegate textViewShouldEndEditing:textView]; 
    } 

    return YES; 
} 

- (void)textViewDidBeginEditing:(UITextView *)textView { 
    if ([_externalDelegate respondsToSelector:@selector(textViewDidBeginEditing:)]) { 
     [_externalDelegate textViewDidBeginEditing:textView]; 
    } 
} 

- (void)textViewDidEndEditing:(UITextView *)textView { 
    if ([_externalDelegate respondsToSelector:@selector(textViewDidEndEditing:)]) { 
     [_externalDelegate textViewDidEndEditing:textView]; 
    } 
} 

- (void)textViewDidChange:(UITextView *)textView { 
    if ([_externalDelegate respondsToSelector:@selector(textViewDidChange:)]) { 
     [_externalDelegate textViewDidChange:textView]; 
    } 
} 

- (void)textViewDidChangeSelection:(UITextView *)textView { 
    if ([_externalDelegate respondsToSelector:@selector(textViewDidChangeSelection:)]) { 
     [_externalDelegate textViewDidChangeSelection:textView]; 
    } 
} 

@end 

एक बड़ा 'पकड़ लिया' जो मुझे इस सवाल का नेतृत्व किया था मैं delegate ओवरराइड करने के लिए _externalDelegate वापस जाने के लिए कोशिश कर रहा था, लेकिन उस वजह से कुछ अजीब दुष्प्रभाव (आंतरिक कोड है कि वास्तविक प्रतिनिधि पर निर्भर करता है वापस करने में होना चाहिए)।