3

在我的应用程序中,我对 UIView 进行了子类化,它在 .m 文件中声明了三个 ivars(2UIButton 和一个 UITextField )。我通过从对象库中拖动 UIView 并将它们转换为我的子类来使用此对象。下面是我的实现

@interface Prescriber()<UITextFieldDelegate>
{
    UIButton *_addButton;
    UIButton *_lessButton;
    UITextField *_valueField;

}
@end
@implementation Prescriber
@synthesize value=_value,intValueofStrig=_intValueofStrig;
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    NSLog(@"prescriber called");
    return self;
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // Drawing code
}
*/
-(void)layoutSubviews
{

    if (!_addButton) {
        _addButton=[[UIButton alloc]init];
        [_addButton addTarget:self action:@selector(addbuttonClicked:) forControlEvents:UIControlEventTouchUpInside];
        [_addButton setBackgroundImage:[UIImage imageNamed:@"add1.png"] forState:UIControlStateNormal];
        _addButton.layer.cornerRadius=5;

    }
    if (!_lessButton) {
        _lessButton=[[UIButton alloc]init];
        [_lessButton addTarget:self action:@selector(lessButoonClicked:) forControlEvents:UIControlEventTouchUpInside];
        [_lessButton setBackgroundImage:[UIImage imageNamed:@"Minus.png"] forState:UIControlStateNormal];
    }
    if (!_valueField) {
        _valueField=[[UITextField alloc]init];
        _valueField.delegate=self;
     }
   ///positioning the addbutton on left corner and right corner and position and   
                textfield in the center 


 }

我已经在 -(void)layoutSubviews 方法中完成了配置代码,因为我的 -initwithFrame 没有被调用,因为它们已经在 xib 文件中。我想知道的是,在 -layoutSubViews 中进行初始化是否正确,因为此方法有可能再次被调用。或者我是否也可以为我的子类视图调用 -viewDidLoad 之类的 delgate 方法?

编辑:- 通过创建 IBOutlet 是可能的,但这种方式对我来说是一个限制。

4

3 回答 3

2

在私有设置方法中执行此操作:

@interface MyViewClass ()
- (void)_setup;
@end

@implementation MyViewClass

- (void)_setup
{
    _addButton=[[UIButton alloc]init];
    [_addButton addTarget:self action:@selector(addbuttonClicked:) forControlEvents:UIControlEventTouchUpInside];
    [_addButton setBackgroundImage:[UIImage imageNamed:@"add1.png"] forState:UIControlStateNormal];
    _addButton.layer.cornerRadius=5;

    _lessButton=[[UIButton alloc]init];
    [_lessButton addTarget:self action:@selector(lessButoonClicked:) forControlEvents:UIControlEventTouchUpInside];
    [_lessButton setBackgroundImage:[UIImage imageNamed:@"Minus.png"] forState:UIControlStateNormal];

    _valueField=[[UITextField alloc]init];
    _valueField.delegate=self;
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self != nil)
    {
        [self _setup];
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self != nil)
    {
        [self _setup];
    }
    return self;
}

@end
于 2013-05-17T06:53:03.127 回答
1

对于 IB 实例,您可以在以下位置设置查看和初始化其子视图-awakeFromNib

- (void)awakeFromNib
{
  [super awakeFromNib];
  // your initialization code here
}

使用此方法,您的实例已完全初始化并已建立 IB 连接。它也保证只被调用一次(每个实例)。如果您还以编程方式创建这种类型的实例,那么您应该考虑一个可以在-awakeFromNib.

在初始化程序中添加子视图的问题是您的视图处于部分构造状态,最终可能会出现副作用或难以以明确定义和确定性的方式初始化您的视图/对象图;-awakeFromNib至少确保所有 NIB 对象都已创建并且连接存在,尽管-awakeFromNib未定义调用顺序。如果您需要精确的排序,那么您应该真正以编程方式处理它。

于 2013-05-17T07:00:35.803 回答
1

我已经在 -(void)layoutSubviews 方法中完成了配置代码,因为我的 -initwithFrame 没有被调用

UIView两个指定的初始化器。当从 nib 加载视图时,-initWithCoder:将调用而不是-initWithFrame:. 您可以将初始化代码放入该方法中,或者将其放入您从两个初始化程序调用的通用初始化方法中。

在 -layoutSubViews 中进行初始化是否正确,因为此方法有可能再次被调用。

这确实是使用-layoutSubviewsfor 初始化的问题:它可能会被多次调用,而且并不总是在视图生命周期的开始。最好使用初始化方法。

于 2013-05-17T06:50:19.890 回答