2012-06-26 44 views
5

UITextView bir alt sınıfım var ve kendi temsilcisini yapmak istiyorum. Böylece textView:shouldChangeTextInRange:replacementText: yöntemini geçersiz kılabilir ve ardışık boşlukların girilmesini önleyebilirim.Kendi temsilci olarak UITextView, sonsuz döngü anlamına gelir

[SATextView awakeFromNib] (SATextView, UITextView alt sınıfımdır), [self setDelegate:self]; yapıyorum. Düzenlemeye başlamak için metin görünümüne bastığımda her şey donar ve sonunda durur ve bu backtrace sonsuz bir döngü olduğunu gösterir. Tüm delege yöntemlerini tek bir uygulamam ya da hiç uygulamam önemli değil. Bu yöntemlerin boş olması da önemli değil.

Bu neden sonsuz bir döngüye neden oluyor? Sadece UITextView ile (diğer nesneleri alt kategoriye ayırabiliyor ve delegeyi kendi başına ayarlayabiliyorsunuz ve bu problemi olmayacak) ortaya çıkıyor. Ve nasıl durdurabilirim? Veya bu alt sınıfın ardışık boşluklara sahip olmaması için daha iyi bir yol var mı?

+0

Bunu bir düşünün. Zor. Bir sınıfın kendi delegesi olması mümkündür, ancak düşünmeyi gerektirir. –

+0

@HotLicks Bununla ilgili bir şeyim var, problemsiz başka sınıflar yaptım mı? Yardım edebilir misin? –

+0

Backtrace, içinde bulunduğunuz döngüyü size göstermelidir. –

cevap

1

Bir fikir ... Gerçek delege ile UITextView arasında orta bir adam gibi davranan bir delege Sınıfı oluşturabilirsiniz. muhtemelen bir süre sonra delege ayarlamanız gerekir). Yani bu yeni sınıf temsilci protokolünü uygulayan, ancak TextView'un iletebilir böylece aynı zamanda da kendi yetki verilen kişi için bir özellik olacaktır: shouldChangeTextInRange: replacementText :, ve hala aracı sınıfında boşluk düzenleme çalışmalarını yapmak.

+0

olarak adlandırılmalıdır, bu benim önerdiğim şeydir. UITextViewDelegate'i uygulayan ve istediğiniz davranışları uygulayan bir yardımcı sınıfı oluşturun. Bu sınıf, genel mantığı yöneten kontrolöre mesaj göndermek için istenirse kendi protokolüne sahip olabilir. Bu desen birçok senaryoda kullanışlıdır, 'UITableViewDataSource' için de kullanıyorum. Güzel, düzenli, yeniden kullanılabilir protokol uygulamaları ile sonuçlanırsınız. – XJones

0

Bir nesneye gözlemci herhangi numaralarını abone olmak mümkündür. Bu yüzden kendisini abone mümkündür:

İşte
@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

Teşekkürler, ancak bildirim merkezi kullanılarak izlenemeyen yöntemlere ihtiyacım var –

0

başarıyla yapmış nasıl bir örnektir. Sadece bazı karakterlerin girilmesini engellemekle ilgiliydim, bu yüzden sadece textView:shouldChangeTextInRange:replacementText:'u uygulayıp geri kalanını geçiriyorum. Bu soruya götürdü

#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 

Bir büyük 'gotcha' ı _externalDelegate dönmek için delegate geçersiz kılmak için çalışıyordu ama o bazı garip yan etkiler (iade edilecek fiili temsilci bağlıdır iç kod olmalıdır neden).