-1

I have a custom UIView which has been loaded into a different UIViewController. I have a button in the custom UIView, which calls a method inside its own class. I want this method to refresh the UIViewController which the UIView is embeded in. Currently I have tried importing the UIViewController to the UIView initializing it and then calling a public method which i have put inside the UIViewController. Nothing that happens inside this method seems to affect it though, I have even tried changing the navigation bar title and that wont work. I know the method is getting called though as it comes up in my log.

Any help?

Nico
  • 1,788
  • 2
  • 23
  • 41
Oli Black
  • 441
  • 2
  • 9
  • 23
  • Please make your question clearer, hopefully with code. Its kind of hard to understand what you want from the block of text. Thanks! – Jack Feb 12 '14 at 22:38
  • it would be very hard to post code for this without it being a very large amount. I basically want to refresh a view from another view. – Oli Black Feb 12 '14 at 22:47
  • Aha, I think in this case what you need is a delegate protocol, see http://stackoverflow.com/questions/6168919/how-do-i-set-up-a-simple-delegate-to-communicate-between-two-view-controllers – Jack Feb 12 '14 at 22:50

1 Answers1

1

This is where a delegation pattern comes into action. If I have not misunderstood, you want to perform some action(refresh??) on a UIViewController based on some action in a UIView, which is in turn is a part of its own view hierarchy.

Lets say your custom view is wrapped in a class CustomView. It has a method named action that is invoked at some point. Moreover, lets assume that you have used CustomView instances to some view controllers, namely, MyViewController1, MyViewController2, etc, as a part of their view hierarchies. Now, you want to perform some action (refresh) in your VCS when action method is triggered from your CustomView instances. For this purpose, you need to declare a protocol in the header file of your CustomView and will have to register a handler of this protocol (commonly known as delegate) to an instance of the CustomView. The header file would look something like this:

//CustomView.h
//your include headers...

@class CustomView;

@protocol CustomViewDelegate <NSObject>
-(void)customViewDidPerformAction:(CustomView*)customView;
@end

@interface CustomView : UIView {
    //......... your ivars
    id<CustomViewDelegate> _delegate;
}

//.......your properties
@property(nonatomic,weak) id<CustomViewDelegate> delegate;

-(void)action;
//....other declarations
@end

Now, you would like customViewDidPerformAction method to be called from any class (like a view controller for "refresh" purpose) whenever action method is triggered. For that purpose, in your implementation file (CustomView.m), you need to invoke the customViewDidPerformAction method stub, if available, from inside your action method:

//CustomView.m
//.......initializer and other codes
-(void)action {
    //other codes

    //raise a callback notifying action has been performed
    if (self.delegate && [self.delegate respondsToSelector:@selector(customViewDidPerformAction:)]) {
        [self.delegate customViewDidPerformAction:self];
    }
}

Now, any class that conforms to CustomViewDelegate protocol can register itself as a receiver of the callback customViewDidPerformAction:. For example, lets say, our MyViewController1 view controller class conforms to the protocol. So the header to the class would look something like this:

//MyViewController1.h
//include headers

@interface MyViewController1 : UIViewController<CustomViewDelegate> 

//........your properties, methods, etc
@property(nonatomic,strong) CustomView* myCustomView;
//......
@end

Then you need to register this class as a delegate of myCustomView, after instantiating myCustomView. Say you have instantiated myCustomView in the viewDidLoad method of the VC. So the method body would be something similar to:

-(void)viewDidLoad {
    ////...........other codes

    CustomView* cv = [[CustomView alloc] initWithFrame:<# your frame size #>];
    cv.delegate = self;
    self.myCustomView = cv;
    [cv release];

    ////......other codes
}

Then you also need to create a method with the same method signature as the protocol declares, inside the implementation(.m) file of the same VC and right your "refresh" code there:

-(void)customViewDidPerformAction:(CustomView*)customView {
    ///write your refresh code here
}

And you are all set. MyViewController1 would execute your refresh code whenever action method is performed by CustomView.

You can follow the same mechanism (conform to CustomViewDelegate protocol and implement customViewDidPerformAction: method) from within any VC, containing a CustomView in its view hierarchy, to refresh itself whenever the action is triggered.

Hope it helps.

Ayan Sengupta
  • 5,238
  • 2
  • 28
  • 40