これはWordにとって扱いにくいですが、コンテナビューを含むView Controller(vc1)があります(ストーリーボードを使用しています)。そのコンテナビュー内には、Navigation ControllerとルートView Controller(vc2)があります。
Vc2内からvc1にアクセスするにはどうすればよいですか?
または、vc1をvc2に渡すにはどうすればよいですか? (私はストーリーボードを使用していることを念頭に置いて)。
ContainerViewControllerが子になると、埋め込みセグエが発生するため、Vc1でprepareForSegue
methodを使用できます。 selfをobjとして渡すか、後で使用するために子への参照を保存できます。
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSString * segueName = segue.identifier;
if ([segueName isEqualToString: @"embedseg"]) {
UINavigationController * navViewController = (UINavigationController *) [segue destinationViewController];
Vc2 *detail=[navViewController viewControllers][0];
Vc2.parentController=self;
}
}
編集:マイナーコード修正
子View Controller内から親View Controllerにアクセスするには、didMoveToParentViewControllerをオーバーライドする必要があります。
- (void)didMoveToParentViewController:(UIViewController *)parent {
[super didMoveToParentViewController:parent];
//Use parent
}
Xcodeコマンド+詳細については、このメソッドをクリックしてください:
これらの2つのメソッドは、子コントローラー間で移行するときに呼び出すコンテナーサブクラスに対してパブリックです。それらがオーバーライドされる場合、オーバーライドは必ずスーパーを呼び出す必要があります。これらの両方のメソッドの親引数は、子がその親から削除されているときはnilです。それ以外の場合は、新しい親View Controllerと同じです。
addChildViewController:は、子を追加する前に[child willMoveToParentViewController:self]を呼び出します。ただし、didMoveToParentViewController:は呼び出されません。コンテナビューコントローラサブクラスは、新しい子への遷移が完了した後、または遷移がない場合はaddChildViewController:の呼び出しの直後にこの呼び出しを行うことが期待されています。同様に、removeFromParentViewController:は、子を削除する前に[self willMoveToParentViewController:nil]を呼び出しません。これは、コンテナサブクラスの責任でもあります。コンテナサブクラスは通常、最初にaddChildViewController:を呼び出して新しい子に移行するメソッドを定義し、次に新しい子のビューをその親のビュー階層に追加し、最後にdidMoveToParentViewController:を呼び出す移行を実行します。同様に、サブクラスは通常、最初に[child willMoveToParentViewController:nil]を呼び出すことにより、逆の方法で子を削除するメソッドを定義します。
プロパティparentViewController
をself.parentViewController
として使用します
Bonnieが使用したのと同じ方法を使用して、委任を使用できます。方法は次のとおりです。
ContainerViews ViewControllerで:
class ContainerViewViewController: UIViewController {
//viewDidLoad and other methods
var delegate: ContainerViewControllerProtocol?
@IBAction func someButtonTouched(sender: AnyObject) {
self.delegate?.someDelegateMethod() //call this anywhere
}
}
protocol ContainerViewControllerProtocol {
func someDelegateMethod()
}
親ViewControllerで:
class ParentViewController: UIViewController, ContainerViewControllerProtocol {
//viewDidLoad and other methods
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "filterEmbedSegue" {
let containerViewViewController = segue.destinationViewController as ContainerViewViewController
containerViewViewController.delegate = self
}
}
func someDelegateMethod() {
//do your thing
}
}
ボニー、どうしたらいいか教えてくれてありがとう。確かに、セグエ法の準備が進むべき道です。
ここでコードと手順を明確にしています。
最初に、コンテナビューを最初のView Controllerに接続するストーリーボードのsegue(link)という名前を付けます。私は「toContainer」という名前を付けました。
次に、コンテナビューを含むView Controllerでこのメソッドを追加します
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString: @"toContainer"]) {
UINavigationController *navViewController = (UINavigationController *) [segue destinationViewController];
UIViewController *vc2 = [navViewController viewControllers][0];
}
}
そのため、vc2は参照したいコントローラーでした。
これは私にとってはうまくいきました。最初のviewconrollerがNavigation Controllerでない場合、メソッドはprepareForSegue内でわずかに異なります。
1)VC2で、VC1への参照を渡すためのプロパティを公開します
//VC2.h
#import "VC1.h"
@interface VC2 : NSObject
@property (strong, nonatomic) VC1 *parent;
@end
2)VC1で、セグエの識別子を「ToVC2」に設定した後、prepareForSegueメソッドでVC2で公開されているプロパティにselfを渡します。次に、参照を次のように渡します。
//VC1.m
@implementation VC1
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([segue.identifier isEqualToString:@"ToVC2"]) {
VC2 *vc2 = segue.destinationViewController;
vc2.parent = self;
}
}
Swift-別の方法は、親UIViewController(vc1)から子/サブビューUIViewController(vc2)への参照と、vc2からvc1への参照を作成することです。以下のparent(vc1)viewDidLoad()の例で参照を割り当てます。
親UIViewController vc1:
class vc1: UIViewController {
@IBOutlet weak var parentLabel: UILabel!
var childVc2: vc2?;
overide func viewDidLoad() {
super.viewDidLoad();
// Use childViewControllers[0] without type/class verification only
// when adding a single child UIViewController
childVc2 = self.childViewControllers[0] as? vc2;
childVc2?.parentVc1 = self
}
}
子UIViewController vc2:
class vc2: UIViewCortoller {
var parentVc1: vc1?;
// At this point child and parent UIViewControllers are loaded and
// child views can be accessed
override func viewWillAppear(_ animated: Bool) {
parentVc1?.parentLabel.text = "Parent label can be edited from child";
}
}
ストーリーボードで、Identity Inspectorで親UIViewContollerクラスをvc1に、子UIViewContollerクラスをvc2に設定することを忘れないでください。 Ctrl + vc1 UIViewControllerのコンテナビューからvc2 UIViewControllerにドラッグして、[埋め込み]を選択します。