iOS 如何在运行时自定义子类实现?

How to customising subclass implementation at runtime in iOS?

MyTextField 是一个 UITextField 子类,在文本字段中有额外的边距。

@interface MyTextField : UITextField
@property (nonatomic, assign) bool enableMargin;
- (instancetype) initWithMarginEnable:(BOOL)enable;
@end

@implementation MyTextField
- (CGRect)textRectForBounds:(CGRect)bounds {

    if(self.enableMargin) return;

    return CGRectInset(bounds, 32.5f, 0);
}

- (CGRect)editingRectForBounds:(CGRect)bounds {
    return [self textRectForBounds:bounds];
}

- (instancetype) initWithMarginEnable:(BOOL)enable {
    self = [super init];
    if(self) {
        self.enableMargin = enable;
    }
    return self;
}
@end

这工作正常!

MyTextField *txt = [[MyTextField alloc] init];

但在我的应用程序中的某些时候,我需要没有任何余量,但是,为了保持连续性并且出于某些充分的原因我仍然必须在整个应用程序中使用 MyTextField

这没有用!

MyTextField *txt = [[MyTextField alloc] initWithMarginEnable:YES];

但在我的个人调查中我意识到 textRectForBounds: 方法总是会在 MyTextField 获取 init.

之前调用

我如何确定(或检查)我是否不需要保证金?我试过使用自定义 init 方法,但它仍然调用 textRectForBounds:.

是的,我的应用程序将支持 iOS7 > 所以任何 advice/suggestion/answer 都应该仅基于此条件:)

您必须在设置 enableMargin 属性 后调用 setNeedsDisplay。您不需要单独制作 init,我会这样做:

 @implementation MyTextField

- (CGRect)textRectForBounds:(CGRect)bounds {

    if(self.enableMargin) return CGRectInset(bounds, 0, 0);;

    return CGRectInset(bounds, 32.5f, 0);
}

- (CGRect)editingRectForBounds:(CGRect)bounds {
    return [self textRectForBounds:bounds];
}

-(void)setEnableMargin:(bool)enableMargin {
    _enableMargin = enableMargin;
    [self setNeedsDisplay];
}

@end

要使用它,您必须调用:

 MyTextField *myText = [[MyTextField alloc] init];
 myText.frame = // whatever the frame will be
 myText.enableMargin = YES;