Я создал класс, который оборачивает UITextView и добавляет некоторые элементы пользовательского интерфейса. Я хочу, чтобы API нового класса был идентичен UITextView, поэтому я использую переадресацию сообщений (листинг ниже) для передачи сообщений между представлением в виде переносимого текста и делегатом.
Раздражает то, что компилятор выдает предупреждения для вызовов методов в экземплярах моего класса пересылки. Например, будет сгенерирована ошибка для следующей строки:
[aMyTextView setContentOffset:CGPointZero animated:YES];
Поэтому я вынужден объявить и создать «перенаправления» реализаций для этих методов, что противоречит цели использования пересылки сообщений.
- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated
{
[_textView setContentOffset:contentOffset animated:animated];
}
Я знаю, что обычный способ обойти это - использовать один из performSelector:
методов, но это) громоздко, когда некоторые аргументы не являются объектами NSO (хотя расширения Эрики Садун очень помогают ), б) опять же, полностью противоречит намерению создать прозрачную обертку.
(Подкласс UITextView также не рассматривается, потому что мне нужно вставить представления под текстовым представлением.)
Есть ли способ обойти это?
Список всех соответствующих частей класса:
@interface MyTextField : UIView<UITextViewDelegate>
{
UIImageView* _border;
UITextView* _textView;
UIButton* _clearButton;
NSObject<UITextViewDelegate>* _delegate;
}
@implementation MWTextField
. . .
// Forwards messages in both directions (textView <--> delegate)
#pragma mark Message forwarding
// Protocol messages will only be sent if respondsToSelector: returns YES
- (BOOL)respondsToSelector:(SEL)aSelector
{
if ([_delegate respondsToSelector:aSelector])
return YES;
else
return [super respondsToSelector:aSelector];
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
// First, try to find it in the UITextView
if ([_textView respondsToSelector:selector])
{
return [_textView methodSignatureForSelector:selector];
}
// Then try the delegate
else if ([_delegate respondsToSelector:selector])
{
return [_delegate methodSignatureForSelector:selector];
}
else
{
return [super methodSignatureForSelector: selector];
}
}
- (void)forwardInvocation:(NSInvocation *)invocation
{
SEL aSelector = [invocation selector];
if ([_textView respondsToSelector:aSelector])
{
[invocation invokeWithTarget:_textView];
}
else if ([_delegate respondsToSelector:aSelector])
{
[invocation invokeWithTarget:_delegate];
}
else
{
[self doesNotRecognizeSelector:aSelector];
}
}
. . .
@end