web-dev-qa-db-ja.com

ストーリーボードinstantiateViewControllerWithIdentifierがIBOutletsを設定しない

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

何が欠けていますか?

これが私の設定です:

  1. ストーリーボードで定義されたビューコントローラーがあります。 instantiateViewControllerWithIdentifier:を呼び出すときに使用する識別子と同じ識別子を指定しました
  2. ビューコントローラー(First Responderのすぐ下)をクリックしてビューの所有者を設定し、Identity Inspectorで、カスタムクラスを、ビューをワイヤリングするクラスと同じ名前に設定しました。
  3. 次に、アシスタントエディターを開き、コントロールがUI要素をドラッグしてIBOutletsIBActionsを作成しました。
37
BlueFish

ビューは、最初にアクセスした後でのみ適切に初期化されているようです。呼び出すときに問題が消えます

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

より簡単に

[vc view];
68
Stefan Henze

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

たぶん良い考えではないかもしれませんが、動作しますが、通常の読み込みに違反しているため、アプリが不安定になります^ _ ^。
誰かがあなたがそれをしたかどうか知りたい場合のために、ここに答えを残します。


私は同じ問題を抱えていましたが、私が設計したカスタムコンポーネントがpresentViewController経由で読み込まれていません(前のビューにオーバーレイで読み込みます)

あなたは単に呼び出すことができます

myViewController.loadView() // Swift

[myViewController loadView] // Obj-C

4
Cesar

人々はビューをロードする方法の解決策を提供しました(一部は決して使用しないでください(loadView())ので、ビューがすでにロードされているかどうかを確認する方法はここにあります

アウトレットがまだ設定されていない場合は明らかに機能しないUIを更新するdidSetオブザーバーを持つプロパティがあったため、この問題に遭遇しました。

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

override func viewDidLoad() {
    super.viewDidLoad()

    updateNameLabel()
}

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

だから今あなたがアウトレットを表示すると更新されますが、プロパティを更新するたびにも

0
hashier

アウトレットはキー値コーディングで確立されます。これをビューコントローラサブクラスに配置できます。

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

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

そして、superへの2つの呼び出しにブレークポイントを設定します。

デバッガで、私は試してみます:

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

  2. [self valueForKey:key]または[self valueForKeyPath:keyPath]または単に[selfアウトレット名]を、superへのコールスルー後に渡された値と比較します。多分あなたはあなたが意図したことをしていないセッターを持っています。 「firstName」のような名前のオブジェクトのアウトレットがあり、次にセレクター「setFirstName:」のアクションがある場合に、このような間違いが数回発生するのを見ました。これはキー値のコーディングを混乱させ、最終的にsetFirstName:アウトレットを確立する目的でnibのロード中に呼び出されますが、アウトレットのセッターはアクションメソッドとして実装されているため、アウトレットは設定されません。

0
Jon Hess

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

詳細については、こちらをご覧ください: IBOutletsはARCの下で強いですか、弱いですか?

0
zgchurch

インスタンス化されたViewControllerのフレームを設定すると、IBOutletsが設定されるようです。

例:

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

これにより、Label、TextField、Button、TableなどのDemoViewControllerのIBOutletsが初期化されます。

お役に立てれば。

0
Sushma Satish