Objective c UITextView子类作为自身的委托

Objective c UITextView子类作为自身的委托,objective-c,ios,cocoa-touch,uiview,uitextview,Objective C,Ios,Cocoa Touch,Uiview,Uitextview,假设我在我的UIView中添加了一个UITextView,我希望它在每次内容更改时都更改其背景色。我可以通过成为UITextView的代表并实现textViewDidChange来做到这一点 但是,如果我经常使用这种行为,那么创建一个UITextView子类是有意义的,我将其称为ColorSwitchingTextView。默认情况下,它应该包括颜色切换行为,这样任何UIView都可以简单地添加颜色切换行为,而不是标准的UITextView 如何从我的ColorSwitchingTextView

假设我在我的
UIView
中添加了一个
UITextView
,我希望它在每次内容更改时都更改其背景色。我可以通过成为
UITextView
的代表并实现
textViewDidChange
来做到这一点

但是,如果我经常使用这种行为,那么创建一个
UITextView
子类是有意义的,我将其称为
ColorSwitchingTextView
。默认情况下,它应该包括颜色切换行为,这样任何
UIView
都可以简单地添加颜色切换行为,而不是标准的
UITextView


如何从我的
ColorSwitchingTextView
类中检测内容的更改?我认为我不能做像self.delegate=self这样的事情

总之,
UITextView
子类如何知道其内容何时更改

编辑
似乎我可以使用
self.delegate=self
,但这意味着使用
ColorSwitchingTextView
的UIViewController也无法订阅通知。一旦我在视图控制器中使用了
switchingTextView.delegate=self
,子类行为就不再有效。有解决办法吗?我正在尝试获取一个自定义的
UITextView
,它在其他方面与常规的
UITextView

类似。在您的子类中,侦听
UITextViewTextDidChangeNotification
通知,并在收到通知时更新背景色,如下所示:

/* 
 * When you initialize your class (in `initWithFrame:` and `initWithCoder:`), 
 * listen for the notification:
 */
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(myTextDidChange)
                                             name:UITextViewTextDidChangeNotification
                                           object:self];

...

// Implement the method which is called when our text changes:
- (void)myTextDidChange 
{
    // Change the background color
}

- (void)dealloc
{
    // Stop listening when deallocating your class:
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

在子类中,将
self
作为观察者添加到
UITextViewTextDidChangeNotification


也就是说,我不同意正在进行的对话,即将
self
设置为代表是一个坏主意。对于这种特殊情况,当然可以,但这只是因为有更好的方法(UITextViewTextDidChangeNotification)。

您可以使用NSNotificationCenter

在子类中将委托设置为self(从未尝试过,但您说过它可以工作),然后在视图控制器中,您要获取通知,请执行以下操作:

[[NSNotificationCenter defaultCenter] 
         addObserver:self 
         selector:@selector(textFieldDidBeginEditing:) 
         name:@"TextFieldDidNotification" object:nil];
在子类中:

NSDictionary *userInfo = [NSDictionary dictionaryWithObject:self forKey:@"textField"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"TextFieldDidBeginEditingNotification" object:self userInfo:userInfo]

现在,您还可以在字典中传递任何其他信息。

最好从一开始就用正确的方式来传递

Apple和SOLID所建议的不是将UITextView子类化,而是将UIView子类化。在自定义UIColorTextView中,成员UITextView将作为子视图,UIColorTextView将作为其委托。此外,UIColorTextView将拥有自己的委托,并将所需的委托回调从UITextView传递给其委托


我有一些类似的任务,不是使用UITextView,而是使用UIScrollView。

“我认为我不能做像self.delegate=self这样的事情”为什么不?它应该可以正常工作。我没有收到任何错误或任何东西,但是将UITextView子类设置为UITextViewDelegate似乎很奇怪-您确定这是正确的方法吗?到目前为止,我还不能让textViewDidChange从内部启动颜色切换TextView。我认为将对象的委托设置为对象本身不是一个好主意。即使它没有抛出任何错误,它也不理想。正确的方法是覆盖UITextView中调用
textViewDidChange
的任何方法。。不幸的是,它似乎是你无法访问/被拒绝的私有代码。。不过我对最后一部分不太确定。。需要更多数字是-基于此线程,将委托设置为self似乎不是一个好主意。此外,它无论如何也不起作用。确保它起作用,我这样做是为了使UITextView和字段具有最大行数和/或字符数。这将把NSNotification传递到-(void)textfieldDendediting:(UITextField*)textField而不是UITextField,如果您希望像正常委托调用一样使用UITextField,这可能会很糟糕。在方法顶部添加类似的内容,以正确获取UITextField。如果([textfield isKindOfClass:[NSNotification class]]){textfield=textfield.object}您将如何在swift中执行此操作?如果您愿意,可以使用通知,但如果您确实希望使用委托,只需在封闭视图中执行。您对“封闭视图”的含义是什么?谢谢Swift版本
NSNotificationCenter.defaultCenter().addObserver(self,选择器:#选择器(ViewControllerNAME.myTextDidChange),名称:UITextViewTextDidChangeNotification,对象:self)
Swift 5版本:
NotificationCenter.default.addObserver(self,选择器:#选择器(myTextDidChange),名称:UITextView.textDidChangeNotification,object:self)
确切地说,只需将包含UITextView的UIView子类化,并使“系统”变得完美。这在UITextView中是不可能的。当然,一般来说,委派=自我并不是一件坏事。解决方案很简单——您使用一个封闭的UIView作为代理——创建了一个很好的系统。