【问题标题】:Protocol/Delegate is not working协议/委托不起作用
【发布时间】:2017-09-18 08:43:47
【问题描述】:

我有三个UIViewcontroller,分别是ViewController、BViewController和CViewController,ViewController是UINavigationController中的RootViewController,

我正在通过按钮操作从 ViewController -> BViewController -> CViewController 推送。

我已经在 CViewController 中声明了协议。这个协议方法在 BViewController 上运行良好,但我不明白如何在 ViewController 中使用它的委托方法。

我在 View Controller 中创建了一个 CViewController 对象,然后为该委托声明了 self,虽然它不起作用,下面是我的代码。请帮我。我在这里做错了!

我的根视图控制器,即ViewController

#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");
}

还有我的第三个 View Controller,我在 .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];
}

【问题讨论】:

    标签: ios objective-c iphone uiviewcontroller delegates


    【解决方案1】:

    如果您尝试将 CViewController 的 Delegate 设置为 ViewController,那么 试试把

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

    关于 CViewController 的 viewDidLoad 方法。

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

    因此,如果您愿意同时在 Viewcontroller 和 BViewController 上执行某些任务,请使用通知模式。 See apple doc here

    【讨论】:

      【解决方案2】:

      在你离开 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];
          }
      }
      

      这不是最好的方法,但它会起作用。

      【讨论】:

      • 是的,你明白了,我必须从 CViewController 到 ViewController 执行一些操作,在你的代码中,在这一行 [delegate conformsToProtocol:testDelegates] 中,“testDelegates”变成红色标记并显示为 Used Undeclared Identifier . :(
      • 对不起,我修改了答案。
      • 完美,完美运行.. 谢谢 :)
      • 这种情况最好的方法是什么?
      【解决方案3】:

      您需要在 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");
      }
      

      【讨论】:

      • 在两个vc中声明协议似乎不是个好主意。我想。我需要从第三个 VC 到第一个 vc 的一些操作
      • O.w 使用了通知中心。在 ViewController 上注册并从 CViewController 类调用。
      • - (void)viewDidLoad { [super viewDidLoad]; CViewController *cVC = [self.storyboard instantiateViewControllerWithIdentifier:@"CViewController"]; cVC.mydelegate = 自我; } 这一行会增加你的应用程序内存。
      • 现在不需要该行了。
      【解决方案4】:

      试试这个

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

      【讨论】:

      • 它的工作,但@Sergey 答案更健壮。不过感谢您的帮助.. :)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多