3

私のアプリケーションでは、UIView をサブクラス化し、.m ファイル (2UIButton と UITextField ) で宣言された 3 つの ivar を持っています。オブジェクト ライブラリから 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 メソッドで構成コードを実行しました。これは、既に xib ファイルにあるため、 -initwithFrame が呼び出されないためです。私が知りたいのは、このメソッドが別の機会に呼び出される可能性があるため、-layoutSubViews で初期化を行うのが正しいかどうかです。または、サブクラス化された View に対しても -viewDidLoad のようなデリゲート メソッドを呼び出すことはできますか?

編集:- 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 接続が確立されます。また、(インスタンスごとに) 1 回だけ呼び出されることも保証されています。このタイプのインスタンスもプログラムで作成する場合は、 で呼び出すことができる共有初期化メソッドを検討する必要があります-awakeFromNib

イニシャライザにサブビューを追加する際の問題は、ビューが部分的に構築された状態にあることです。最終的には、副作用や、ビュー/オブジェクト グラフを適切に定義された決定論的な方法で初期化することが困難になる可能性があります。が呼び出される順序は定義されていませんが-awakeFromNib、少なくともすべての NIB オブジェクトが作成され、接続が存在することを確認します。-awakeFromNib正確な順序付けが必要な場合は、実際にプログラムでアプローチする必要があります。

于 2013-05-17T07:00:35.803 に答える
1

-initwithFrame が呼び出されないため、 -(void)layoutSubviews メソッドで構成コードを実行しました

UIView2 つの指定されたイニシャライザがあります。ビューが nib から読み込まれると、 の-initWithCoder:代わりに が呼び出され-initWithFrame:ます。そのメソッドに初期化コードを入れるか、両方の初期化子から呼び出す共通の初期化メソッドに入れることができます。

このメソッドが別の機会に呼び出される可能性があるため、-layoutSubViews で初期化を行うのは正しいですか。

これは実際、-layoutSubviews初期化に使用する際の問題です。複数回呼び出される可能性があり、常にビューの有効期間の最初に呼び出されるとは限りません。初期化メソッドを使用することをお勧めします。

于 2013-05-17T06:50:19.890 に答える