从View中调用ViewController中的实例方法

时间:2014-07-09 09:41:43

标签: ios objective-c

我试图从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 ..."

1 个答案:

答案 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通过协议松散耦合。