调用具有多个子视图层次结构的协议方法

Posted

技术标签:

【中文标题】调用具有多个子视图层次结构的协议方法【英文标题】:Calling protocol method with multiple subview hierarchy 【发布时间】:2012-03-11 22:07:37 【问题描述】:

我是 Obj-C 的新手,正在学习如何使用协议和委托。

当只有两个视图时,按照示例实现协议/传递数据没有问题,但是,当我有多个子视图时尝试调用方法时出现“无法识别的选择器”错误。

例如,在我有的场景中

FirstViewController SecondViewController 第三视图控制器

我希望 ThirdViewController 回调 FirstViewController。

通用代码类似于:

在 FirstViewController.h 中

@interface FirstViewController : UIViewController <MyProtocol>

在 firstViewController.m 中

//present a second controller which will control settings for the app
SecondViewController *secondViewController = [[SecondViewController alloc]     initWithNibName:@"secondViewController" bundle:nil];

secondViewController.delegate= self;

secondViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;

[self presentModalViewController: secondViewController animated: YES];

以后

-(void) aMethod
    //carry out some action here

在 secondViewController.m 中

//present a third controller...maybe a table view for selecting music   
ThirdViewController *thirdViewController = [[ThirdViewController alloc] initWithNibName:@"thirdViewController" bundle:nil];

thirdViewController.delegate= self;

thirdViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;

[self presentModalViewController: thirdViewController animated: YES];

在 ThirdViewContoller.h 中

//Create a protocol to implement options back on the firstViewController
@protocol MyProtocol;

@interface thirdViewController

    IBOutlet UIButton *aButton;


@property (nonatomic, weak) id<MyProtocol> delegate;
-(IBAction) callMethod:(id)sender;
@end

@protocol MyProtocol <NSObject>
- (void) aMethod;
@end

在 ThirdViewController.m 中

@synthesize delegate;

-(IBAction) callMethod:(id)sender
    [self.delegate aMethod];

运行时,消息似乎只发送回 secondViewController 而不是 firstViewController 因为错误是:

-[SecondViewController aMethod:]:无法识别的选择器发送到实例 0x19d620

我认为设置代理出口有一些基本概念尚未学习,或者程序结构错误。

这里有很多只使用两个视图的代码示例,但我没有找到关于多个视图的太多信息。如果我的程序设计真的不正确,我提前道歉。

【问题讨论】:

【参考方案1】:

您需要SecondViewController 以符合您的协议:

@interface SecondViewController : UIViewController <MyProtocol>

您正在尝试调用仅存在于第一个视图控制器中的第二个视图控制器上的方法。如果您想与第一个视图控制器进行通信,则必须定义第二个协议来执行此操作。

这是一个非常好的学术练习,可以了解协议的功能和限制,但您还应该注意命名冲突。在命名您的协议时,请尽量使用描述性。理想情况下,您应该有一组如下所示的头文件:

@interface FirstViewController : UIViewController <SecondViewControllerDelegate>
@end

还有第二个视图控制器:

@protocol SecondViewControllerDelegate <NSObject> 
-(void)someSecondViewControllerDelegateMethod;
@end

@interface SecondViewController : UIViewController <ThirdViewControllerDelegate>

@protocol (nonatomic, weak) id <SecondViewControllerDelegate> delegate;

@end

最后是第三个视图控制器:

@protocol ThirdViewControllerDelegate <NSObject> 
-(void)someThirdViewControllerDelegateMethod;
@end

@interface ThirdViewController : UIViewController

@protocol (nonatomic, weak) id <ThirdViewControllerDelegate> delegate;

@end

所以第二个视图控制器可以实现-(void)someThirdViewControllerDelegateMethod,它可能看起来像:

-(void)someThirdViewControllerDelegateMethod

    [self.delegate someFirstViewControllerDelegateMethod];

这就是第三个视图控制器可以回调第一个视图控制器的方式;它有点级联并传递消息。

【讨论】:

我很高兴这对你有用!如果您对我的回答满意,请考虑将答案标记为“已接受”。

以上是关于调用具有多个子视图层次结构的协议方法的主要内容,如果未能解决你的问题,请参考以下文章

具有层次结构的网格自定义命令正在调用 javascript 函数两次。

如何在视图控制器层次结构中正确设置 interfaceOrientation 属性?

iOS10 UI教程层次结构的事件

在 UIView 中调用 UIViewController 视图作为子视图的问题

在所有子视图自动布局之前调用 viewWillTransitionToSize

UIView层次管理