View does not have default method to access its view-controller object.
You need to pass the view-controller object into the view object yourself.
Typical way to do this is making a property.
@class ViewController;
@interface DraggableView : NSObject
@property (readwrite,nonatomic,assign) ViewController* theOwnerViewController;
@end
@implementation DraggableView
- (void)testCallingOwnerViewControllerMethod
{
[self.theOwnerViewController test];
}
@end
You need to set the theOwnerViewController
after you created the DraggableView
object.
- (void)loadView
{
draggableView = [[DraggableView alloc]initWithFrame:CGRectMake(20, 190, 280, 280)];
draggableView.theOwnerViewController = self;
//...extra view setup.
}
Use assign
to avoid retain-cycle on the property.
Delegate pattern
You can do this by above pattern, but as you noticed, you need to know and forward-declare the owner view-controller class' name from its view (which is sub-node of the VC). Usually This is bad design choice because it's easily makes circular dependency (or backward dependency), which usually creates tight-coupling.
Instead, you can use delegate pattern to avoid circular dependency issue.
@protocol TestDelegate
- (void)test;
@end
@interface DraggableView : NSObject
@property(readwrite,nonatomic,assign) id<TestDelegate> testDelegate;
@end
@implementation DraggableView
- (void)test
{
[self.testDelegate test];
}
@end
You need to set the testDelegate
after you created the DraggableView
object.
@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
In this case, you don't have to know the class name of the view object before you create. Any class which conforms TestDelegate
protocol can be used, and now the view and VC are loosely-coupled via the protocol.