拦截子类中的 Objective-C 委托消息
我有一个 UIScrollView 的子类,其中我需要在内部响应滚动行为。但是,视图控制器仍然需要侦听滚动委托回调,因此我无法直接窃取组件内的委托。
有没有办法保留名为“delegate”的属性并仅侦听沿其发送的消息,或者以某种方式在内部劫持委托属性并在运行某些代码后向外转发消息?
I have a subclass of UIScrollView in which I need to internally respond to scrolling behaviour. However, the viewcontroller will still need to listen to scrolling delegate callbacks, so I can't outright steal the delegate within my component.
Is there a way to keep the property named "delegate" and just listen to messages sent along it, or else somehow internally hijack the delegate property and forward messages outward after running some code?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
为了避免手动覆盖所有委托方法,您可以使用消息转发。我只是使用中间代理类实现了同样的事情,如下所示:
MessageInterceptor.h
MessageInterceptor.m
MyScrollView.h
MyScrollView.m (已编辑,感谢jhabbott):
通过这种方法,
MessageInterceptor
对象会自动将所有委托消息转发到常规委托对象,除了您在自定义子类中重写的消息。To avoid overriding all of the delegate methods manually, you can use message forwarding. I just implemented the same thing using an intermediate proxy class as follows:
MessageInterceptor.h
MessageInterceptor.m
MyScrollView.h
MyScrollView.m (Edited, with thanks to jhabbott):
With this approach, the
MessageInterceptor
object will automatically forward all delegate messages to the regular delegate object, except for the ones that you override in your custom subclass.e.James 的帖子为大多数视图提供了一个很好的解决方案。但对于像 UITextField 和 UITextView 这样依赖键盘的视图,通常会导致无限循环的情况。为了摆脱它,我用一些额外的代码修复了它,这些代码检查选择器是否包含在特定协议中。
WZProtocolInterceptor.h
WZProtocolInterceptor.m
这是 Swift 2 版本:
The post from e.James gave an excellent solution for most views. But for keyboard dependent views like UITextField and UITextView, it often results in a situation of infinite loop. To get rid of it, I fixed it with some additional code what checks whether the selector is contained in specific protocol(s) or not.
WZProtocolInterceptor.h
WZProtocolInterceptor.m
And here is the Swift 2 version:
实际上,这对我有用:
...在 e.James 给出的精彩答案中使子类成为消息拦截器。
Actually, this worked for me:
...making the subclass to be the message interceptor in the awesome answer given by e.James.
是的,但是您必须重写 文档。基本上,创建第二个委托属性并实现委托协议。当调用委托方法时,请处理您的事务,然后从刚刚运行的委托方法中调用第二个委托上的相同方法。例如
Yes, but you'll have to override every delegate method in the docs. Basically, make a second delegate property and implement the delegate protocol. When your delegate methods are called, take care of your business and then call the same method on your second delegate from the delegate method that was just run. E.g.