从堆栈中的第 3 个 ViewController 调用 navigationController 的根 ViewController 中的方法 - iOS

Call method in navigationController's rootViewController from a 3rd ViewController in the stack - iOS

我的 navigationControllers 层次结构是这样的:

vc1 -> vc2 -> vc3

我想在 vc3 解雇时从 vc3 调用 vc1 方法。

我尝试实现委托,但由于 vc1 没有 vc3 对象,所以没有成功。

(vc3 是在 segue 时从 vc2 创建的)

I tried to implement delegates but since vc1 doesn't have a vc3 object, it didn't work.

是的,但是当您在 v2 的生命周期范围内创建 v3 时,您可以同时访问 v1 和 v3(我想,您可以 link 在 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 中同时访问 v1 和 v3)。 更新:尝试使用 self.navigationController.viewControllers[0] 检索 vc1。

试试这个代码: 创建三个视图控制器 视图控制器1 视图控制器2 ViewController3

//ViewController1.h

    #import <UIKit/UIKit.h>
    #import "ViewController2.h"
    #import "ViewController3.h"


    @interface ViewController1 : UIViewController <callDelegate>

    @end

//ViewController1.m

#import "ViewController1.h"
#import "ViewController2.h"

@interface ViewController1 ()

@end

@implementation ViewController1 

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.


    ViewController3 *v3=[[ViewController3 alloc]init];
    v3.mydelegate=self;


    ViewController2 *v2=[[ViewController2 alloc]init];
    v2.myView=v3;
    [self.navigationController pushViewController:v2 animated:YES];


    UILabel *lbl=[[UILabel alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
    [self.view addSubview:lbl];
    self.view.backgroundColor=[UIColor whiteColor];
    lbl.backgroundColor=[UIColor redColor];
lbl.text=@"v1";



}

-(void)delegateCalled{
    NSLog(@"I am V1");
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

//ViewController2.h

#import <UIKit/UIKit.h>
#import "ViewController3.h"


@interface ViewController2 : UIViewController 
@property(nonatomic,strong) UIViewController *myView;
@end

//ViewController2.m

#import "ViewController2.h"
#import "ViewController3.h"

@interface ViewController2 ()

@end

@implementation ViewController2 

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

//    ViewController3 *v3=[[ViewController3 alloc]init];
//   self.myView.mydelegate=self;
    [self.navigationController pushViewController:self.myView animated:YES];


    UILabel *lbl=[[UILabel alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
    [self.view addSubview:lbl];
    self.view.backgroundColor=[UIColor whiteColor];
    lbl.backgroundColor=[UIColor redColor];

    lbl.text=@"V2";

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

//ViewController3.h

#import <UIKit/UIKit.h>
@protocol callDelegate <NSObject>

-(void)delegateCalled;

@end
@interface ViewController3 : UIViewController 
@property(nonatomic,weak)id<callDelegate>mydelegate;

@end

//ViewController3.m

#import "ViewController3.h"

@interface ViewController3 ()

@end

@implementation ViewController3

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    UIButton *lbl=[[UIButton alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
    [self.view addSubview:lbl];
    self.view.backgroundColor=[UIColor whiteColor];
lbl.backgroundColor=[UIColor redColor];
    [lbl setTitle:@"v3" forState:UIControlStateNormal];
    [lbl addTarget:self action:@selector(buttonClick) forControlEvents:UIControlEventTouchUpInside];

}
-(void)viewDidDisappear:(BOOL)animated{
    [self.mydelegate delegateCalled];

}

-(void)buttonClick{
    [self.mydelegate delegateCalled];
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end