Передача установщиков / получателей переменной экземпляра в класс

Я работаю над созданием подкласса UIView (который я называю MarqueeLabel) который анимирует подпредставление UILabel ivar в виде выделения, когда текст UILabel слишком длинный для содержащего представления.

Я надеялся получить чистую реализацию, без необходимости писать методы в моем MarqueeLabel класс просто для установки / извлечения всех стандартных переменных экземпляра UILabel (текст, шрифт, цвет и т. д.) в экземпляре UILabel ivar. Я нашел способ сделать это с пересылкой сообщений - все нераспознанные методы отправлены MarqueeLabel передаются в UILabel ivar. В моем случае методы, не признанные MarqueeLabel методы, обычно используемые с UILabel.

Есть некоторые проблемы с этим подходом, хотя:
1. Вы должны использовать [marqueeLabel setText:@"Label here"], скорее, чем marqueeLabel.text
2. Компилятор выдает предупреждения в приведенной выше строке, потому что:

"MarqueeLabel" может не отвечать на "-setText:"

которую я буду знать, чтобы игнорировать, но раздражать кого-либо еще.

Чтобы избежать этих проблем, есть ли способ "выдвинуть" методы ивара, чтобы они были доступны для чего-то, использующего класс, при этом воздействуя на объект ивара?

Спасибо!

Примечание: способ, которым я настроил это, может быть не лучшим способом сделать это также. Возможно, подкласс или продолжение класса UILabel было бы лучше, но я не мог понять, как анимация + обрезка (когда прокручиваемый текст выходит за пределы UIView и исчезает), могут быть выполнены с помощью этих методов.

Примечание 2: я знаю, что вы можете использовать marqueeLabel.subLabel.text где subLabel это подвид UILabel. И это может быть направление, которое я выберу, но с тем же успехом могу посмотреть, есть ли лучшее решение!

1 ответ

Решение

Для свойств вы можете определить свойство в интерфейсе и использовать @dynamic в реализации, чтобы вам не приходилось создавать реализации-заглушки. Убедитесь, что вы также переопределите valueForUndefinedKey: а также setValue:forUndefinedKey: и вперед на ваш лейбл.

Для любых методов, которые не являются частью свойства, вы можете использовать категорию для объявления метода без его реализации. Это избавит от предупреждений, но все равно будет использовать встроенную пересылку.

//MarqueeLabel.h
#import <UIKit/UIKit.h>
@interface MarqueeLabel : UIView {}
@property (nonatomic, copy) NSString *text;
@end
@interface MarqueeLabel (UILabelWrapper)
- (void)methodToOverride;
@end

//MarqueeLabel.m
#import "MarqueeLabel.h"
@implementation MarqueeLabel
@dynamic text;
- (id)valueForUndefinedKey:(NSString *)key {
    return [theLabel valueForKey:key];
}
- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
    [theLabel setValue:value forKey:key];
}
@end
Другие вопросы по тегам