从另一个'm'文件调用方法

时间:2012-10-31 00:23:54

标签: objective-c

我的应用程序的大部分代码都在名为 MyViewController 的'm'文件中。该应用程序实现了一个包含UIWebView对象的自定义UIView。 UIView和UIWebView的代码保存在一个名为 CustomUIView 的单独“m”文件中。

我已设法使用委托覆盖UIWebView对象中的URL超链接的点击次数。但是,我希望这些点击启动一个存储在我的主应用程序代码中的方法。此方法称为“popupView”,并采用单个参数“inputArgument”。 inputArgument是用户单击的URL的文本。实际上,这种方法与导致我的自定义UIView启动的方法完全相同。

无论如何,我想要做的是让我重写的URL点击导致 popupView 方法启动,从而导致另一个UIView在点击的那个上面打开。

问题是检测到URL点击的'm'文件无法看到'popupView'方法,因为它包含在 MyViewController 'm'文件中。如何从另一个'm'文件中调用 popupView 方法?

2 个答案:

答案 0 :(得分:2)

直接

  1. MyViewController中声明-popupView:的方法MyViewController.h
  2. {li> #import MyViewController.h位于CustomUIView.m
  3. CustomUIView提供MyViewController个[{1}}实例的引用,例如@property中声明的CustomUIView.h
  4. 对于(1)@interface的{​​{1}}(MyViewController)应该看起来有点像这样

    MyViewController.h

    对于@interface MyViewController : UIViewController { //.... } - (void)popupView:(NSString *)urlText; //.... @end (2)应该在顶部附近的某处

    UIViewController.m

    对于#import "CustomUIView.h" #import "MyViewController.h" (3)中的@interface应该类似于

    CustomUIView.h

    在创建@interface CustomUIView : UIView { //.... } @property (nonatomic, weak) MyViewController *viewController; @end 所拥有的CustomUIView实例后,需要设置此属性。如果您的MyViewController位于CustomUIView,则可以通过将关键字MyViewController.xib添加到属性声明中来设置此属性

    IBOutlet

    并将此属性指向@property (nonatomic, weak) IBOutlet MyViewController *viewController; 中的“文件所有者”。相反,如果您以编程方式创建XIB,则可以在初始化后立即在其上设置此属性。

    代表

    然而,这远非一种最佳做法。使用delegate pattern会好得多。要做到这一点,你需要

    1. 定义代理protocol
    2. 将“委托”CustomUIView添加到@property
    3. 在适当的时间调用委托对象上的委托方法。
    4. CustomUIView
    5. 中实施协议
    6. MyViewController实例拥有的@property实例的“委托”CustomUIView设置为MyViewController个实例。
    7. 让我们将我们的委托协议称为像MyViewController这样具有想象力的东西。对于CustomUIViewDelegate,我们会将其声明在(1)的顶部,如下所示:

      CustomUIView.h

      请注意,我们必须forward declare我们的类@class CustomUIView; @protocol CustomUIViewDelegate <NSObject> - (void)customUIView:(CustomUIView *)customView didSelectURLText:(NSString *)urlText; @end ,以便编译器能够理解协议方法CustomUIView中第一个参数的类型。

      对于customUIView:didSelectURLText:,我们会做一些与上面的(2)非常相似的事情:您的(3) CustomUIView看起来像

      @interface

      同样,如果我们要在Interface Builder中设置此属性,我们需要使用@interface CustomUIView : UIView { //.... } @property (nonatomic, weak) id<CustomUIViewDelegate> *delegate; @end 关键字向IB宣布:

      IBOutlet

      对于(3),我们需要在适当的时间在委托对象@property (nonatomic, weak) IBOutlet id<CustomUIViewDelegate> *delegate; 上调用委托方法customUIView:didSelectURLText:

      在你的问题中,你写了

        

      我已设法使用委托来覆盖UIWebView对象中的URL超链接的点击次数。

      所以,让我们说self.delegate有一个实例方法

      CustomUIView
      当用户在UIWebView中选择一个链接时,调用

      。需要告知- (void)didSelectURL:(NSURL *)url { //.... } 的代表:

      CustomUIView

      请注意,我们首先检查- (void)didSelectURL:(NSURL *)url { //... if ([self.delegate respondsToSelector:@selector(customUIView:didSelectURLText:)]) { { [self.delegate customUIView:self didSelectURLText:url.absoluteString]; } } 实例的委托对象是否通过调用CustomUIView来实现感兴趣的选择器(customUIView:didSelectURLText:)。

      对于respondsToSelector:,我们需要首先(4)添加到<CustomUIViewDelegate>的{​​{1}}声明,并确保{{1 }} MyViewController到我们使用符号@interface的文件中。我们的#import CustomUIView.h看起来像这样:

      CustomUIViewDelegate

      更重要的是,我们需要在MyViewController的{​​{1}}中实施 @interface协议;到目前为止,我们只宣称#import "CustomUIView.h" @interface MyViewController : UIViewController <CustomUIViewDelegate> { //.... } //.... @end 采用了它。

      为此,由于我们的协议只包含一种方法,因此我们只需添加自己的CustomUIViewDelegate实现。我们的MyViewController @implementation看起来像这样:

      MyViewController

      最后,对于-customUIView:didSelectURLText:,我们需要设置MyViewController实例拥有的@implementation实例的#import "MyViewController.h" @implementation MyViewController //.... - (void)popupView:(NSString *)urlText { //.... } #pragma mark - CustomUIViewDelegate - (void)customUIView:(CustomUIView *)customView didSelectURLText:(NSString *)urlText { [self popupView:urlText]; } //.... @end 属性。我不完全了解(5)与其delegate实例的关系,以描述如何明确地做到这一点,但我将提供一个示例:我将假设您以编程方式,在{ {1}}将CustomUIView添加为MyViewController视图的子视图。所以MyViewController的实现看起来有点像这样:

      CustomUIView

      此时剩下要做的就是将局部变量-[MyViewController loadView]的{​​{1}} CustomUIView设置为MyViewController

      -loadView

      修改:根据- (void)loadView { [super loadView]; //.... CustomUIView *customView = //.... //.... [self.view addSubview:customView]; //.... } delegate之间关系的新信息更新(5)。

      在您的评论中,您写道@property被添加为customView的子视图,其中selfcustomView.delegate = self; CustomUIView的实例方法MyViewController。因此,您注意到撰写CustomUIView与撰写cvc.view相同,这显然不是您想要做的。

      您希望将cvc的{​​{1}}属性设置为CustomUIViewController的实例。因此,您的方法CustomUIView应该类似于

      -[CustomUIView show]

      其中customView.delegate = self;self.delegate = self的实例。

答案 1 :(得分:0)

好吧,既然你正在编写CustomUIView,为什么不实现像initWithPopupDelegate:(MyViewController *)delegate这样的构造函数,并在实例变量中保持对MyViewController实例的引用,然后调用方法在那。

(在@class MyViewController;顶部添加CustomUIView.h,在#import "MyViewController.h"顶部添加CustomUIView.m,以便编译器知道您正在使用的课程。)

或者,如果只有一个MyViewController实例,则可以为MyViewController定义一个类方法,例如+ (MyViewController *)instance,并返回对一个实例的引用(您存储在类变量中并在创建实例时第一次设置,请参阅“单例模式”)。但是,如果不知道代码的具体细节,我建议第一个解决方案(委托)更简单,更灵活。