我试图从UIView中调用我的UIViewController中的实例方法。在我的UIViewController中,我有类似的东西:
-(void) test {
NSLog(@"test");
}
在我的UIViewController中,我创建了一个我的UIView的实例,如下所示:
draggableView = [[DraggableView alloc]initWithFrame:CGRectMake(20, 190, 280, 280)];
在我的draggableView
中,我想调用test
实例方法。如何在不创建UIViewController的新实例的情况下执行此操作?
我有tried this,但它似乎不是一个非常优雅的解决方案,我收到错误"No visible @interface ..."
答案 0 :(得分:3)
View没有默认方法来访问其view-controller对象。 您需要自己将视图控制器对象传递给视图对象。 这样做的典型方法是建造房产。
@class ViewController;
@interface DraggableView : NSObject
@property (readwrite,nonatomic,assign) ViewController* theOwnerViewController;
@end
@implementation DraggableView
- (void)testCallingOwnerViewControllerMethod
{
[self.theOwnerViewController test];
}
@end
您需要在创建theOwnerViewController
对象后设置DraggableView
。
- (void)loadView
{
draggableView = [[DraggableView alloc]initWithFrame:CGRectMake(20, 190, 280, 280)];
draggableView.theOwnerViewController = self;
//...extra view setup.
}
使用assign
以避免在属性上保留周期。
您可以通过上述模式执行此操作,但正如您所注意到的,您需要知道并向前声明所有者视图控制器类'视图中的名称(VC的子节点)。通常这是糟糕的设计选择,因为它很容易产生circular dependency(或向后依赖),这通常会产生紧耦合。
相反,您可以使用委托模式来避免循环依赖性问题。
@protocol TestDelegate
- (void)test;
@end
@interface DraggableView : NSObject
@property(readwrite,nonatomic,assign) id<TestDelegate> testDelegate;
@end
@implementation DraggableView
- (void)test
{
[self.testDelegate test];
}
@end
您需要在创建testDelegate
对象后设置DraggableView
。
@interface ViewController<TestDelegate>
@end
@implementation
- (void)test
{
// do something.
}
- (void)loadView
{
draggableView = [[DraggableView alloc]initWithFrame:CGRectMake(20, 190, 280, 280)];
draggableView.testDelegate = self;
//...extra view setup.
}
@end
在这种情况下,您在创建之前不必知道视图对象的类名。可以使用任何符合TestDelegate
协议的类,现在视图和VC通过协议松散耦合。