协议/委托不工作

问题描述:

我有三个的UIViewController,即视图控制器,BViewController和CViewController,视图控制器是RootViewController的距离的UINavigationController,协议/委托不工作

我是从推的ViewController - > BViewController - > CViewController,通过按钮操作。

我已经在CViewController中声明了协议。这个协议方法对BViewController工作正常,但我不明白如何在ViewController中使其委托方法工作。

我已经在View Controller中创建了CViewController对象,然后为该代理声明了自己,尽管它不工作,下面是我的代码。请帮帮我。我在这里做错了!

我的根视图控制器,即视图控制器

#import "ViewController.h" 
#import "BViewController.h" 
#import "CViewController.h" 

@interface ViewController()<testDelegates> 

@end 

@implementation ViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    CViewController *cVC = [self.storyboard instantiateViewControllerWithIdentifier:@"CViewController"]; 
    cVC.mydelegate = self; 
} 

- (IBAction)nextAction:(id)sender { 

    BViewController *bViewC = [self.storyboard instantiateViewControllerWithIdentifier:@"BViewController"]; 

    [self.navigationController pushViewController:bViewC animated:YES]; 
} 

-(void)TestMethod{ 

    NSLog(@" Its NOT Working"); 
} 

我的第二个视图控制器,即BViewController

#import "BViewController.h" 
#import "CViewController.h" 

@interface BViewController()<testDelegates> 

@end 

@implementation BViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
} 

- (IBAction)bNextAction:(id)sender { 

    CViewController *cVC = [self.storyboard instantiateViewControllerWithIdentifier:@"CViewController"]; 

// cVC.mydelegate = self; 
    [self.navigationController pushViewController:cVC animated:YES]; 
} 

-(void)TestMethod{ 

    NSLog(@" Its Working If I uncomment to cVC.mydelegate = self"); 
} 

我的第三个视图控制器,在这里我声明在协议。 h文件,即CViewController

#import <UIKit/UIKit.h> 

@protocol testDelegates <NSObject> 

-(void)TestMethod; 

@end 

@interface CViewController : UIViewController 

@property (weak) id <testDelegates> mydelegate; 

@end 

而在.m文件

#import "CViewController.h" 

@interface CViewController() 

@end 

@implementation CViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
} 

- (IBAction)cNextAction:(id)sender { 

    [self.mydelegate TestMethod]; 
} 

创建和这个类摧毁你离开viewDidLoad方法之后。

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    CViewController *cVC = [self.storyboard instantiateViewControllerWithIdentifier:@"CViewController"]; 
    cVC.mydelegate = self; 
} 

据我所知,你需要在CViewController中执行ViewController中的一些方法。

您可以将viewController作为委托传递给BViewController,并将它们传递给CViewController。

或者你可以用这样的代码:

- (IBAction)cNextAction:(id)sender { 
    id<testDelegates> delegate = self.navigationController.viewControllers[0]; 
    if([delegate conformsToProtocol:@protocol(testDelegates)]) 
    { 
     [delegate TestMethod]; 
    } 
} 

这不是最好的方式,但它会工作。

+0

是的,你得到了,我必须从CViewController执行一些操作到ViewController,在你的代码中,在这一行[delegate conformsToProtocol:testDelegates]中,“testDelegates”变成红色标记并且使用未声明的标识符。 :( –

+0

对不起,我已经修改回答 – Sergey

+0

完美,完美工作..谢谢:) –

试试这个

self.delegate = self.navigationController.viewControllers[0]; 
+0

它的工作,但@Sergey答案更鲁棒。感谢您的帮助虽然.. :) –

您需要声明另一个协议到BViewController类。

Please follow below steps. 

第1步:BViewController.h

@protocol testDelegates2 <NSObject> 

-(void)TestMethod2; 

@interface BViewController : UIViewController 

@property (weak) id <testDelegates> mydelegate; 


@end 
@implementation CViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
} 

- (IBAction)cNextAction:(id)sender { 

    [self.mydelegate TestMethod2]; 
} 

Step 2. In ViewController class conform Protocol 
@interface ViewController()<testDelegates> 

@end 

@implementation ViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    CViewController *cVC = [self.storyboard instantiateViewControllerWithIdentifier:@"CViewController"]; 
    cVC.mydelegate = self; 
} 

- (IBAction)nextAction:(id)sender { 

    BViewController *bViewC = [self.storyboard instantiateViewControllerWithIdentifier:@"BViewController"]; 
cVC.mydelegate = self; //important line 
    [self.navigationController pushViewController:bViewC animated:YES]; 
} 

-(void)TestMethod2{ 

    NSLog(@"Final Output"); 
} 
+0

它似乎不是好主意通过在两个vc声明协议。我认为。我需要从第三个VC到第一个vc –

+0

O.w使用的通知中心。在ViewController上注册并从CViewController类调用。 –

+0

虽然,它不是个好主意:/ –

如果你正在尝试CViewController的代表设置的ViewController然后 尝试把

self.mydelegate = self.navigationController.viewControllers[0] 

上CViewController的viewDidLoad方法。

否则您正试图使ViewController和BViewController都成为CViewController的委托,那么这不可能像这样,因为对象的委托只能是唯一的。这意味着委托只是一个变量,用于保存对象的引用,因为您知道变量的值在某个时刻可以是唯一的。

所以如果你愿意在Viewcontroller和BViewController上做一些任务,那么就使用通知模式。 See apple doc here