Я создал класс, который обертывает UITextView и добавляет некоторые элементы ui. Я хочу, чтобы API нового класса был идентичен с UITextView, поэтому я использую пересылку сообщений (список ниже) для передачи сообщений между обернутым текстовым представлением и делегатом.Избегание предупреждений компилятора при выполнении пересылки сообщений
Раздражает то, что компилятор выдает предупреждения для вызовов методов в экземплярах моего класса переадресации. Например, ошибка будет генерироваться для следующей строки:
[aMyTextView setContentOffset:CGPointZero animated:YES];
Поэтому я вынужден объявить и создавать «вручную переадресации» реализаций этих методов, побеждает вся цель использования пересылки сообщений.
- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated
{
[_textView setContentOffset:contentOffset animated:animated];
}
Я знаю, что обычный способ обойти это, чтобы использовать один из performSelector:
методов, но это) громоздки, когда некоторые аргументы не являются NSObjects (хотя Erica Sadun's extensions большая помощь), б) снова, полностью противоречит намерению создать прозрачную оболочку.
(подклассов 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
Ваше решение: приятно, но было бы еще лучше не декларировать методы, а просто пересылать их, какими бы они ни были. Подкласс: я хочу сгруппировать фактическое текстовое поле с некоторыми элементами, по крайней мере одно из которых должно появиться * под * текстовым полем. Если я подклассифицирую UITextField, все, что я могу сделать с другими представлениями, это добавить их как subviews, что означает, что они будут поверх текстового поля. Думаю, я мог бы изменить drawRect: ... Это то, что вы предложили бы? Или у тебя там рукава? – Felixyz
Но как вы могли исправить пересылку без предупреждения и предупреждения, когда вы имеете в виду? Экспедирование чрезвычайно динамично. Что касается подклассификации, вы можете сделать что-либо в своем подклассе, который вы делаете в своем пользовательском классе. – bbum
Вы правы, конечно. Если я сделаю эти предупреждения, то все остальные тоже уйдут, что не будет хорошо. Таким образом, ваше решение для протокола кажется лучшим. Подкласс не смог бы поставить представление под (в терминах порядка рисования) сам, потому что это представление было бы subview и как таковое всегда располагалось над родительским представлением. Правильно? – Felixyz