2012-09-21 13 views
36

私はストーリーボードinstantiateViewControllerWithIdentifier:を使用していますが、私が配線したIBOutletsのすべてがまだゼロであることに気付いています。しかし、IBActions私は仕事をしています。ビューとコントローラはリンクされています(つまり、controller.viewはゼロではありません)。ビューを表示すると、私は期待しているものを表示します。ストーリーボードinstantiateViewControllerWithIdentifierがIBOutletsを設定していません

私には何が欠けていますか?私は私のストーリーボードで定義されたビューコントローラを持っている

  1. は、ここに私のセットアップです。 instantiateViewControllerWithIdentifier:

  2. View Controller(First Responderの下)をクリックしてビューの所有者を設定し、アイデンティティ・インスペクタの下にカスタム・クラスを設定しました。私はビューを配線したいクラスと同じ名前です。
  3. 次に、私はアシスタントエディタを開き、コントロールはUI要素をドラッグしてIBOutletsIBActionsを作成しました。

    - (void)setValue:(id)value forKeyPath:(NSString *)keyPath { 
        [super setValue:value forKeyPath:keyPath]; 
    } 
    
    - (void)setValue:(id)value forKey:(NSString *)key { 
        [super setValue:value forKeyPath:key]; 
    } 
    

    を、スーパーへの二つの呼び出しにブレークポイントを置く:

+0

私は自分のペン先にビューを壊そうとしましたが、私は同じ問題を抱えています。 initWithNibName:bundle:IBでctrl-click-dragで定義されていても、IBOutletを設定していないようです。 – BlueFish

+0

回避策として、[[NSBundle mainBundle] loadNibNamed:@ "myNib" owner:controller options:nil]を使用しています。これはペン先をロードし、IBOutletsをコントローラーの値に割り当てます。しかし、同じことをしているようなコントローラのメソッドがある場合、これは間違っているようです。 – BlueFish

+0

あなたの設定とちょっと混乱していますが、なぜあなたはビューのオーナーを設定していますか?あなたのibのアウトレットはストーリーボードのビューコントロールに置かれますか?このビューコントローラーをインスタンス化するときに、カスタムヘッダーと実装に一致するようにこのVCのタイプを設定すると、アウトレットが機能するはずです。 – Pochi

答えて

64

ビューは、最初にアクセスされた後で初めて適切に初期化されているようです。インスタンス化のViewControllerのためのフレームを設定

単に
[vc view]; 
+6

これは本当に奇妙です。つまり、これが適切な行動であるかどうか知っていますか?私があなたの答えを見つけるまで、これは今二日間ナッツを運転していました。 – jere

+0

これが適切かどうかわかりませんが、わかりやすいです。ビューコントローラーが作成されただけなので、ビューとすべてをセットアップする理由。 View Controllerを持っているときにビューが必要だと思うかもしれませんが、どのような最適化がこの動作につながったのかは分かります。それはどこかで文書化されるべきです。 –

+0

このソリューションは私のために働いた - ありがとう。 – user1295558

0

アウトレットは、キー値コーディングで確立されている、あなたはあなたのビューコントローラのサブクラスにこれを入れることができます。デバッガで

、私が試してみた:

  1. をあなたがにコンセントを適用していると思うビューコントローラへの「自己」を比較します。おそらくあなたのストーリーボードには、期待していない2番目のビューコントローラーがあります。あなたが「所有者を設定した」と言ったとき、私はそれが奇妙な用語であると思った。既に存在する表現に加えて、ビュー・コントローラーを表すためにキューブ・オブジェクトの1つをドラッグしましたか?

  2. スーパーに通話した後、値が渡された[self valueForKey:key]または[self valueForKeyPath:keyPath]または[self outletName]と比較してください。たぶん、あなたがしようとしていることをしていないセッターがいるかもしれません。私はこのような間違いが、「firstName」のような名前を持つオブジェクトのコンセントを持っていて、次にセレクタ「setFirstName:」を持つアクションが2〜3回起こっているのを見てきました。これはキー値のコーディングを混乱させ、setFirstNameで終わります。出口を確立する意図で呼び出し中に呼び出されますが、コンセントのセッターはアクションメソッドとして実装されるため、コンセントは決して設定されません。

1

[self presentViewController:vc animated:NO completion:nil]; 

以上を呼び出すときに問題が消えるIBOutletsを設定しているようです。

例:

DemoViewController *demoVC = [[self storyboard] instantiateViewControllerWithIdentifier:@"demoVC"]; 
demoVC.frame = self.view.frame; //or CGRectMake(0, 0, 1015, 604); 

これはラベル、テキストフィールド、ボタン、表などのようなDemoViewControllerのIBOutletsを初期化します、。

これが役に立ちます。

+3

これは 'view'にアクセスしています。これはビュー階層の内側にあるコンセントに適用されます(カスタム 'NSObject'のものではありません)。 –

0

リンク先のオブジェクトがArrayControllerのようにシーン内の最上位のエンティティである場合、参照はビュー階層によって保持されていないため、強く(弱くはありません)する必要があります。弱い参照は、あなたが記述しているような問題を引き起こす可能性があります。詳細については、こちらを

ルック:たぶんShould IBOutlets be strong or weak under ARC?

5

[悪い例として私を使用]

ない良いアイデア結局、^それは動作しますが、それはアプリが不安定になって、通常のロードに違反します_ ^。
他の誰かがあなたがそれをするかどうかを知りたい場合に備えて、ここで答えを残しておきます。


私は同じ問題が、しかし、私が設計したカスタムコンポーネントがpresentViewController介してロードされていません(前のビューにオーバーレイで負荷)

を持っていたあなたは、単に

myViewController.loadView()を呼び出すことができます/ /スイフト

[myViewController loadView] //オブジェクト - C

+5

文書から:** 'あなたはこのメソッドを直接呼び出すべきではありません。最初に私はこのコードを盲目的にコピーしましたが、私のビューはロードされましたが、私は説明できない他の問題に遭遇しました。このコードを削除すると、すべてが機能しました。このメソッドを呼び出さないことを強くお勧めします。 – hashier

+0

私は上記のコメントに従わないことをお勧めします – Warrick

0

人がHの溶液が得られました(loadView())を使用するべきではありませんので、あなたのビューが既にロードされているかどうかを確認する方法です。

私はdidSetオブザーバー出口はまだそれを回避する方法をいくつかのサンプルコードであるので、ここで設定されていない場合は明らかに動作しませんUI:

var name: String? { 
    didSet { 
     updateNameLabel() 
    } 
} 

override func viewDidLoad() { 
    super.viewDidLoad() 

    updateNameLabel() 
} 

func updateRoomLabel() { 
    guard isViewLoaded() else { 
     return 
    } 
    [...] 
} 

だから今、あなたはコンセントを表示するときにも、あなたが更新されるたびに更新されますが取得しますプロパティ

関連する問題