0

編集#1

質問の下部にある編集 #1 をお読みください。カスタム ビューの作成に nib を使用できるすべての方法を理解しようとしているので、すべての例で nib ファイルを扱います。

終わり

コントローラーでペン先を使用するカスタム ビューを作成するためのすべての手法を理解しようとしています。この質問の一番下に方法をリストしました。

これが私の TRtestview のコードです (この設定方法の 1 つの意味は、initWithCoder が常に呼び出されることです)。

// TRtestview.m
-(id)initWithCoder:(NSCoder *)aDecoder{
    self=[super initWithCoder:aDecoder];
    if (self) {
      if (self.subviews.count == 0) {
        UIView *myView=[[[NSBundle mainBundle] loadNibNamed:@"testview" owner:nil options:nil] lastObject];
        myView.userInteractionEnabled=YES;  // doesn't do anything
        [self addSubview:myView];
      }
    }
    NSLog(@"about to return here in initWithCoder");
    return self;
}

編集 1

-(void)setup
{
       UIView *myView=[[[NSBundle mainBundle] loadNibNamed:@"testview" owner:nil options:nil] lastObject];
      [self addSubview:myView];
}


- (id)initWithFrame:(CGRect)frame
{
    NSLog(@"at top of initWithFrame");
    self = [super initWithFrame:frame];
    if (self) {
      [self setup];
    }
    return self;
}

TRViewController.m で、thisView を userInteractionEnabled に設定しようとしましたが、状況は変わりませんでした。

- (void)viewDidLoad
{
  [super viewDidLoad];
  self.thisView.userInteractionEnabled=YES;

これは、initWithFrame (手法 1) と loadNibNamed (手法 2) を呼び出すシナリオで機能しました。ビューをオブジェクト インスペクタからドラッグしてロードし、カスタム クラス属性インスペクタでクラスを設定します (手法 #3)。ただし、ボタンは機能しないため、この方法は機能しません。

テクニック 3 を使用して nib を使用してカスタム ビューを作成し、ユーザーの操作を許可するにはどうすればよいですか?

どうも

編集 1

カスタム ビューを作成してインスタンス化する方法をすべて理解したいと思います。理想的には、initWithFrame、loadNibNamed、またはオブジェクト ライブラリからドラッグして作成できるカスタム ビューを使用できるようにしたいと考えています。

シナリオは次のようです。

  1. ViewController からの initWithFrame; ペン先で使用する場合、initWithFrame で loadNibNamed を呼び出します - 再帰的な読み込みを防ぐ必要があります
  2. ViewController (initWithCoder を呼び出す) から loadNibNamed を取得し、一度だけロードしたい
  3. UIView のインスタンスをドラッグし、カスタム クラスをカスタム UIView (この場合は TRtestview) に設定します。これは initWithCoder を呼び出します。
4

1 に答える 1

1

サブビューが再帰的にならないように、サブビューのハッキーなチェックを使用して、testview クラスのイニシャライザ内から testview をロードしているようです。おそらく外部のコードも nib をロードするので、ここで実際に行っているのは、nib を 2 回ロードすることです。所有者を設定すると、内側の所有者が外側のアウトレットに設定されます。

確かに知るには十分な情報がないため、これは推測にすぎませんが、ビュークラス内のサブビューの一部に対してアウトレットを設定している場合は、クラスのタイプでownerオブジェクトを提供する必要があります。したがって、コードで所有者としてloadNibNamed:owner:options:渡すことができ、これが機能する可能性があります。selfただし、シングルビューにペン先を使用するのは実際には間違った方法です。

nib ファイルの単一ビューをTRtestViewクラスにする代わりに、単一ビューを他の内部ビューのホルダーとして使用し、「ファイルの所有者」プレースホルダー オブジェクトをクラスに設定しTRtestviewます。ホルダーのアウトレットを作成して割り当ててから、次のようにします。

TRtestview* testview = [[TRtestview alloc] initWithFrame:desiredFrame];
[[NSBundle mainBundle] loadNibNamed:@"testview" owner:testview options:nil];

testviewサブビューとして追加できるホルダーを含め、ペン先がロードされると、すべてのアウトレットが設定されます。

また、異なる nib 内でTRtestviewを使用したい場合 (たとえばTestViewController、と呼ばれる。次に、上記のコードの 2 行目を forに入れ、アウトレットを所有者オブジェクトとして渡します。TRtestviewTRtestviewinitWithCoderTestViewControllertestviewawakeFromNibTestViewControllertestview

編集:何をしようとしているのかを正確に確認するのは難しいですが、ビューの init メソッド内から nib をロードするのは間違っています (nib をロードするとビュー オブジェクトが作成されますが、その逆ではありません)。最初は、設定したい s がどこにあるかを誤解していたと思いIBOutletます。おそらく、探している答えは、実際には nib をロードできるが、次のようなクラス コンストラクター メソッドから取得できるということです。

+ (MyCustomView*)newCustomView
{
    MyCustomView* view = [[NSBundle mainBundle] loadNibNamed:@"testview" owner:nil options:nil][0];
    // Do custom setup things to view here...
    // Perhaps based on additional inputs to this method.
    view.doStuff;
    return view;
}
于 2013-07-10T23:14:33.617 に答える