直接地
- 中声明
MyViewController
的方法-popupView:
。MyViewController.h
#import
MyViewController.h
在CustomUIView.m
.
- 提供
CustomUIView
对 的 [one] 实例的引用MyViewController
,例如通过在 中@property
声明的方式CustomUIView.h
。
对于(1)
,@interface
( MyViewController
in MyViewController.h
) 应该看起来有点像这样
@interface MyViewController : UIViewController
{
//....
}
- (void)popupView:(NSString *)urlText;
//....
@end
对于(2)
,UIViewController.m
应该在顶部附近的某个地方有以下内容
#import "CustomUIView.h"
#import "MyViewController.h"
因为(3)
,@interface
inCustomUIView.h
应该看起来像
@interface CustomUIView : UIView
{
//....
}
@property (nonatomic, weak) MyViewController *viewController;
@end
CustomUIView
在创建owned by实例后的一段时间内,需要设置此属性MyViewController
。如果您CustomUIView
是 in MyViewController.xib
,则可以通过将关键字添加IBOutlet
到属性声明中来设置此属性,如下所示
@property (nonatomic, weak) IBOutlet MyViewController *viewController;
并将此属性指向XIB
. 相反,如果您以CustomUIView
编程方式创建,则可以在初始化后立即在其上设置此属性。
代表
然而,这远非最佳实践。使用委托模式会好得多。为此,您需要
- 定义一个委托协议。
- 添加一个“代表”
@property
到CustomUIView
.
- 在适当的时候调用委托对象的委托方法。
- 在
MyViewController
.
@property
将实例所CustomUIView
拥有的实例的“委托”设置MyViewController
为MyViewController
实例。
让我们将委托协议称为富有想象力的东西,例如CustomUIViewDelegate
. 对于(1)
,我们将在顶部声明CustomUIView.h
如下:
@class CustomUIView;
@protocol CustomUIViewDelegate <NSObject>
- (void)customUIView:(CustomUIView *)customView didSelectURLText:(NSString *)urlText;
@end
请注意,我们必须前向声明我们的类CustomUIView
,以便编译器能够理解协议方法中第一个参数的类型customUIView:didSelectURLText:
。
对于(2)
,我们将做一些与上面非常相似的事情(3)
:您CustomUIView
@interface
将看起来像
@interface CustomUIView : UIView
{
//....
}
@property (nonatomic, weak) id<CustomUIViewDelegate> *delegate;
@end
同样,如果我们要在 Interface Builder 中设置此属性,我们将需要使用IBOutlet
关键字向 IB 宣布它:
@property (nonatomic, weak) IBOutlet id<CustomUIViewDelegate> *delegate;
对于(3),我们需要在适当的时候调用customUIView:didSelectURLText:
委托对象的委托方法。self.delegate
在你的问题中,你写了
我已经设法使用委托覆盖对 UIWebView 对象中的 URL 超链接的点击。
所以,假设CustomUIView
有一个实例方法
- (void)didSelectURL:(NSURL *)url
{
//....
}
当用户在 UIWebView 中选择一个链接时调用它。的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>
toMyViewController
的@interface
声明,并确保添加到#import
CustomUIView.h
我们使用符号的文件中CustomUIViewDelegate
。我们MyViewController
的 '@interface
看起来像这样:
#import "CustomUIView.h"
@interface MyViewController : UIViewController <CustomUIViewDelegate>
{
//....
}
//....
@end
更重要的是,我们需要在's中实现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
实例的属性。我对' 与其实例的关系知之甚少,无法明确描述如何执行此操作,但我将提供一个示例:我假设您以编程方式将 '添加为' 视图的子视图。所以你的实现看起来有点像这样:CustomUIView
MyViewController
MyViewController
CustomUIView
-[MyViewController loadView]
CustomUIView
MyViewController
-loadView
- (void)loadView
{
[super loadView];
//....
CustomUIView *customView = //....
//....
[self.view addSubview:customView];
//....
}
此时剩下要做的就是delegate
@property
将局部变量的设置customView
为self
:
customView.delegate = self;
编辑CustomUIView
:根据有关和之间关系的新信息更新(5)MyViewController
。
在您的评论中,您写道您CustomUIView
被添加为cvc.view
where cvc
is an instance of CustomUIViewController
inCustomUIView
的子视图-[CustomUIView show]
。因此,您注意到写作customView.delegate = self;
与写作相同self.delegate = self
,这显然不是您想要做的。
您想将CustomUIView
' 的delegate
属性设置为 的实例MyViewController
。因此,您的方法-[CustomUIView show]
应该类似于
- (void)show
{
//....
[cvc.view addSubview:self];
self.delegate = mvc;
}
mvc
的实例在哪里MyViewController
。