1

我正在创建一个 UIView 子类(我正在调用它MarqueeLabel),当 UILabel 文本对于包含视图而言太长时,它会以选取框方式为子视图 UILabel ivar 设置动画。

我希望有一个干净的实现,而不必在我的类中编写方法MarqueeLabel设置/检索 UILabel ivar 的所有标准 UILabel(文本、字体、颜色等)实例变量。我找到了一种通过消息转发来做到这一点的方法——所有发送到的无法识别的方法都被传递给 UILabel ivar。在我的情况下,无法识别的方法是通常与 UILabel 一起使用的方法。MarqueeLabelMarqueeLabel

但是这种方法存在一些问题:
1.您必须使用[marqueeLabel setText:@"Label here"],而不是marqueeLabel.text
2.编译器在上面的行中给出警告,因为:

“MarqueeLabel”可能不响应“-setText:”

我会知道忽略但会惹恼其他任何人。

为了避免这些问题,有没有办法将方法“提出”一个 ivar,以便使用类的东西可以访问它们,同时仍然作用于 ivar 对象?

谢谢!

注意:我设置的方式可能也不是最好的方式。也许子类化或类继续 UILabel 会更好,但我无法掌握如何使用这些方法完成动画 + 剪辑(当滚动的文本移出包含 UIView 并消失时)。

注2:我知道你可以使用子视图UILabelmarqueeLabel.subLabel.text在哪里。subLabel这可能是我采取的方向,但不妨看看是否有更好的解决方案!

4

1 回答 1

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
于 2011-02-04T03:26:20.200 回答