我有一个UITextView的子类,我想把它作为自己的委托。这样我就可以覆盖textView:shouldChangeTextInRange:replacementText:
方法,并防止输入连续的空格。
在[SATextView awakeFromNib]
(SATextView是我的UITextView的子类)中,我做[self setDelegate:self];
。当我按下textview开始编辑时,所有内容都冻结并最终停止,并且该回溯显示存在无限循环。
如果我实现所有委托方法,只有一个或没有,这没关系。如果这些方法是空的也没关系。
为什么会导致无限循环?只有使用UITextView(其他对象可以子类化并将委托设置为self,并且它不会出现此问题),似乎只会发生这种情况。我怎么能阻止它?或者有更好的方法让这个子类不能有连续的空格,
答案 0 :(得分:1)
一个想法......你可以创建一个委托类,作为真正的委托和UITextView之间的中间人(因为你可能需要在一段时间后设置委托)。所以这个新类将实现委托协议,但是它也有自己的委托属性,这样你就可以转发textView:shouldChangeTextInRange:replacementText:,并且仍然可以在middleMan类中编辑空格。
答案 1 :(得分: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:@" "];
}
答案 2 :(得分: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
,但这会产生一些奇怪的副作用(必须有内部代码取决于实际代表将被退回)。