209

iOS6では、新しいコンテナビューに気づきましたが、含まれているビューからそのコントローラにアクセスする方法がよくわかりません。

シナリオ:

例

コンテナビューを格納するビューコントローラからアラートビューコントローラのラベルにアクセスしたい。

それらの間にセグエがあります、私はそれを使うことができますか?

4

11 に答える 11

367

はい、セグエを使用して、子ビューコントローラ(およびそのビューとサブビュー)にアクセスできます。alertview_embedストーリーボードの属性インスペクターを使用して、セグエに識別子(など)を付けます。次に、親ビューコントローラー(コンテナービューを格納するコントローラー)に次のようなメソッドを実装させます。

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
   NSString * segueName = segue.identifier;
   if ([segueName isEqualToString: @"alertview_embed"]) {
       AlertViewController * childViewController = (AlertViewController *) [segue destinationViewController];
       AlertView * alertView = childViewController.view;
       // do something with the AlertView's subviews here...
   }
}
于 2012-11-07T22:56:10.813 に答える
57

これは簡単に行うことができますself.childViewControllers.lastObject(子供が 1 人しかいない場合、それ以外の場合は を使用しますobjectAtIndex:)。

于 2012-11-08T00:11:26.007 に答える
28

スウィフトプログラミング用

あなたはこのように書くことができます

var containerViewController: ExampleViewController?
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    // you can set this name in 'segue.embed' in storyboard
    if segue.identifier == "checkinPopupIdentifierInStoryBoard" {
        let connectContainerViewController = segue.destinationViewController as ExampleViewController
        containerViewController = connectContainerViewController
    }
}
于 2015-03-29T08:02:06.903 に答える
19

このprepareForSegueアプローチは機能しますが、セグエ識別子のマジック ストリングに依存しています。たぶんもっと良い方法があります。

目的の VC のクラスがわかっている場合は、計算されたプロパティを使用してこれを非常にうまく行うことができます。

var camperVan: CamperVanViewController? {
  return childViewControllers.flatMap({ $0 as? CamperVanViewController }).first
  // This works because `flatMap` removes nils
}

これは に依存しchildViewControllersます。最初のものに頼るのはもろいかもしれないことに同意しますが、求めるクラスに名前を付けると、これは非常に堅実に見えます。

于 2016-04-30T07:47:35.347 に答える
9

計算されたプロパティを使用した Swift 3 の更新された回答:

var jobSummaryViewController: JobSummaryViewController {
    get {
        let ctrl = childViewControllers.first(where: { $0 is JobSummaryViewController })
        return ctrl as! JobSummaryViewController
    }
}

これは、最初の一致に達するまで子のリストを反復するだけです。

于 2016-10-16T02:22:50.887 に答える
8

self.childViewControllers 親からの制御が必要な場合は、より関連性があります。たとえば、子コントローラーがテーブル ビューであり、それを強制的にリロードしたり、ボタン タップやその他の親ビュー コントローラーのイベントを介してプロパティを変更したりしたい場合は、prepareForSegue 経由ではなく、ChildViewController のインスタンスにアクセスすることで実行できます。どちらも異なる方法でアプリケーションを持っています。

于 2014-10-05T09:10:25.767 に答える
2

View Controller のタイプで Swift の switch ステートメントを使用する別の方法があります。

override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
  switch segue.destination
  {
    case let aViewController as AViewController:
      self.aViewController = aViewController
    case let bViewController as BViewController:
      self.bViewController = bViewController
    default:
      return
  }
}
于 2016-12-30T12:16:29.997 に答える
1

私は次のようなコードを使用します:

- (IBAction)showCartItems:(id)sender{ 
  ListOfCartItemsViewController *listOfItemsVC=[self.storyboard instantiateViewControllerWithIdentifier:@"ListOfCartItemsViewController"];
  [self addChildViewController:listOfItemsVC];
 }
于 2016-05-18T11:01:09.403 に答える
1

誰かがSwift 3.0を探している場合、

viewController1viewController2などにアクセスできるようになります。

let viewController1 : OneViewController!
let viewController2 : TwoViewController!

// Safety handling of optional String
if let identifier: String = segue.identifier {

    switch identifier {

    case "segueName1":
        viewController1 = segue.destination as! OneViewController
        break

    case "segueName2":
        viewController2 = segue.destination as! TwoViewController
        break

    // ... More cases can be inserted here ...

    default:
        // A new segue is added in the storyboard but not yet including in this switch
        print("A case missing for segue identifier: \(identifier)")
        break
    }

} else {
    // Either the segue or the identifier is inaccessible 
    print("WARNING: identifier in segue is not accessible")
}
于 2016-11-25T01:13:23.340 に答える
0

あなたはこのように書くことができます

- (IBAction)showDetail:(UIButton *)sender {  
            DetailViewController *detailVc = [self.childViewControllers firstObject];  
        detailVc.lable.text = sender.titleLabel.text;  
    }  
}
于 2016-08-17T11:41:26.040 に答える