12

I am trying to dismiss a UIPopoverViewControler from a button in the Popover. In addition I want it to transfer the data back to the main view. I have it working for a modalViewController but not for a Popover. Does anyone know how I can achieve this?

//popover

- (IBAction) save:(id)sender
{
    if ([self startDateIsValid] && [self endDateIsValid]) 
    {

        [[self parentViewController] setDatesForEvent:startDate eventEndDate:endDate allDay:[allDaySwitch isOn]];
        [self dismissModalViewControllerAnimated:YES];

    }

}

//AddEventViewController_iPad

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "dateViewPopOverViewController_iPad.h"
@interface AddEventViewController_iPad : UIViewController <UITableViewDelegate,UITableViewDataSource, MFMailComposeViewControllerDelegate, UITextFieldDelegate,  UIAlertViewDelegate,UIPopoverControllerDelegate,UINavigationControllerDelegate,UIPopoverControllerDelegate,ABPeoplePickerNavigationControllerDelegate, ABNewPersonViewControllerDelegate,DismissPopoverDelegate> {

//datePopover

#import <UIKit/UIKit.h>
#import "AddEventViewController_iPad.h"
@protocol DismissPopoverDelegate <NSObject>

- (void) dismissWithData:(NSString *)data;

@end

@interface dateViewPopOverViewController_iPad : UIViewController<UIPopoverControllerDelegate> {
P.J.Radadiya
  • 1,493
  • 1
  • 12
  • 21
BDGapps
  • 3,318
  • 10
  • 56
  • 75

3 Answers3

23

Idea is simple. YourViewController - it's viewController of UIPopoverController. MainViewController - controller where you create UIPopoverController

  1. Declare protocol in YourViewController with dismiss method
  2. Declare property of type id<DismissDelegateProtocol> in YourViewController
  3. Declare support of DismissDelegateProtocol in MainViewController
  4. Implement dismiss method of DismissDelegateProtocol in MainViewController
  5. When you create YourViewController in MainViewController set delegate property (yourViewController.delegate = self;)
  6. In action, that response to button touching call delegate method: [self.delegate dismissWithData:dataToTransfer];

In code it should be like this:

In MainViewController.h:

#import "YourViewController.h"
@class MainViewController: UIViewController < DismissPopoverDelegate >

In MainViewController.m:

- (void) dismissPopover:(NSObject *)yourDataToTransfer
{ /* Dismiss you popover here and process data */ }

...
// Some method, when you create popover
{
    YourViewController *vc = ... ;
    vc.delegate = self; // this delegate property should be declared as assign
}

In YourViewController.h:

@protocol DismissPopoverDelegate
- (void) dismissPopover:(NSObject *)yourDataToTransfer;
@end

@class YourViewController : UIViewController
{
    id<DismissPopoverDelegate> delegate;
}

@property (nonatomic, assign) id<DismissPopoverDelegate> delegate;

In YourViewController.m:

- (void) methodWhenYouWantToDismissPopover
{
    [self.delegate dismissPopover:data];
}
TodK
  • 1,079
  • 10
  • 17
5hrp
  • 2,230
  • 1
  • 18
  • 18
  • im getting an error on the line @class YourViewController : UIViewController { id delegate; } it says i need a ; – BDGapps May 07 '11 at 16:24
  • it says i need a ; instead in @class AddEventViewController_iPad : UIViewController – BDGapps May 07 '11 at 16:32
  • what are u considering as the YourViewController.h and the MainViewController.h – BDGapps May 07 '11 at 16:35
  • Look at my updated post. YourViewController - it's viewController of UIPopoverController. MainViewController - controller where you create UIPopoverController – 5hrp May 07 '11 at 16:42
  • putinng @class MainViewController: UIViewController < DismissPopoverDelegate > above the interface where I import everything doesn't work I still have that error – BDGapps May 07 '11 at 16:46
  • Add `@protocol DismissPopoverDelegate;` line before MainViewController class declaration – 5hrp May 07 '11 at 16:50
  • `@protocol DismissPopoverDelegate; @class AddEventViewController_iPad: UIViewController < DismissPopoverDelegate > @interface AddEventViewController_iPad : UIViewController {` – BDGapps May 07 '11 at 16:53
  • Read my answer again. I've decribed all as clealy as it could be – 5hrp May 07 '11 at 17:05
  • where in the .h are u putting it because i keep getting errors `@class MainViewController: UIViewController < DismissPopoverDelegate >` – BDGapps May 07 '11 at 17:16
  • 4
    I've create example project for you. Get it [here](http://dl.dropbox.com/u/8107006/PopoverExample.zip) – 5hrp May 07 '11 at 17:44
  • i have tried your code and it seemed to work but I'm getting one error when i put it into mine it says DismissPopoverDelegate cant find protocol even though i imported the popover with the protocol. can u help me with this. thanks – BDGapps May 07 '11 at 21:10
  • If you can't implement absolutely clear answer with working example - that doesn't mean that answer is incorrect. Think about it – 5hrp May 07 '11 at 22:17
  • Ok i rechecked it, sorry i'm new to it and didn't know what i'm supposed to do. – BDGapps May 07 '11 at 22:20
  • Sorry it only my first day can you try to answer my other post. Thanks – BDGapps May 07 '11 at 22:50
  • This seems like the same way you usually handle UIModalViewController. I wish Apple would just add support to UIViewController for this stuff... Even if they just defined the delegate to call back and you implemented it. – LightningStryk May 09 '13 at 22:50
  • I feel like I can't vote up enough this answer. F***ing awesome! Thanks! – Andra Todorescu Jan 28 '14 at 09:45
12

Sharrps answer is perfectly good, but here's a slightly different approach that may be quicker if you're presenting a subclassed view controller.

So if you've subclassed the UIViewController that's being presented, define a property on it pointing to a UIPopoverController. In your presenting view controller, instantiate your custom view controller, instantiate your popover with said custom view controller, then assign the custom view controller it's property to point to the popover controller containing it.

When it comes time to dismiss, your controller has a reference to it's popover and can dismiss it. The popover will also have a pointer to it's parent view controller, so you can perform any actions you need with regards to your model via your original presenting view controller.

isaac
  • 4,867
  • 1
  • 21
  • 31
  • 3
    This is smart. I am going to shun the accepted answer and go this way. Apple should have made this simpler. When you ask a fellow to get out and he says, ask my father to take me away, it can be pretty annoying. – gigahari Mar 21 '13 at 10:01
  • Way easier than accepted answer—am accustomed to passing objects and data amongst classes this way, but didn't think of implementing dismissing the popover like this from within the presented VC. – Evan R Mar 12 '14 at 15:51
1

In the original dialogue above "im getting an error on the line @class YourViewController : UIViewController { id delegate; } it says i need a ; – BDGapps"

The answer is very simple. It's a type. Change @class to @interface and all is well.

@protocol DismissPopoverDelegate
- (void) dismissPopover:(NSObject *)yourDataToTransfer;
@end


@interface YourViewController : UIViewController {
    id<DismissPopoverDelegate> delegate;
}
Jim Holland
  • 1,180
  • 12
  • 19