2012-06-10 2 views
11

Я читал тонн вещей в этом и в то время как большинство из них, похоже, относится к подходу, не предназначенному для раскадровки, я думал, что я собрал кусочки вместе и понял это. Однако следующий код не приводит к увольнению моего popover. Кнопка throwPopoverButtonPressed в Popover выполняется, но точка останова в методе rejectPopover в делегате никогда не попадает. Очень хотел бы, чтобы кто-то бросил взгляд на код, чтобы обнаружить ошибки.Раскадровка: Отклонение Поповера с использованием метода делегирования/протокола

Благодаря

Далее NewGameViewController содержит UIButton. При нажатии на это появляется Popover Segue и последующее отображение popover, содержащего UIView PopViewController.

NewGameViewController.h

#import "PopViewController.h" 
@interface NewGameViewController: UIViewController <DismissPopoverDelegate> 
{ 
    UIPopoverController *popover; 
} 

NewGameViewController.m

@implementation NewGameViewController 
-(void)prepareForSegue:(UIStoryboardPopoverSegue *)segue sender:(id)sender 
{ 
    if ([[segue identifier] isEqualToString:@"popoverSegue"]) 
    { 
     popover = [(UIStoryboardPopoverSegue *)segue popoverController]; 
     // getting warning: Assigning to 'id<UIPopoverControllerDelegate>' from incompatible type 'NewGameViewController *const__strong' 
     //popover.delegate = self; 
    } 
} 

-(void)dismissPopover 
{ 
    [popover dismissPopoverAnimated:YES]; 
} 

PopViewController.h

@protocol DismissPopoverDelegate <NSObject> 
-(void) dismissPopover; 
@end 

@interface PopViewController: UIViewController 
{ 
    __unsafe_unretained id<DismissPopoverDelegate> delegate; 
} 

@property (nonatomic, assign) id<DismissPopoverDelegate> delegate; 
-(IBAction)dismissPopoverButtonPressed:(id)sender; 
@end 

PopViewController.m

#import "NewGameViewController.h" 
@implementation PopViewController 
@synthesize delegate; 
-(IBAction)dismissPopoverButtonPressed:(id)sender 
{ 
    [self.delegate dismissPopover]; 
} 

ответ

13

При соединении с контроллером поповера из раскадровки Segue, то popoverController свойства Segue относится к стандартному UIPopoverController. Сам этот контроллер имеет свойство, contentViewController, которое будет представлять контроллер представления, который фактически отображается в popover, в вашем случае PopViewController.

Таким образом, ваш текущий код устанавливает себя как делегат контроллера popover, когда ему действительно нужно настроить себя как делегат контента.

Вам все еще нужно сохранить ссылку на контроллер поповер вокруг, чтобы отклонить, так держать существующий код, но сделать следующие изменения:

-(void)prepareForSegue:(UIStoryboardPopoverSegue *)segue sender:(id)sender 
{ 
    if ([[segue identifier] isEqualToString:@"popoverSegue"]) 
    { 
     popover = [(UIStoryboardPopoverSegue *)segue popoverController]; 
     // Get a reference to the content view controller of the popover 
     PopViewController *popVC = (PopViewController*)popover.contentViewController; 
     // Set ourselves as the content VC's delegate 
     popVC.delegate = self; 
    } 
} 
+0

Спасибо. Должен признаться, я реализовал этот код, не полностью понимая логику, но я помню, как читал несколько комментариев о том, что нужно явно объявить протокол и делегировать, чтобы события Popover можно было обрабатывать в VC, который его генерирует. Разумеется, подходы кажутся разными в зависимости от того, создается ли Popover явно в коде и через раскадровку. С учетом сказанного, я все еще не мудрее на выше. – Tony

+0

Я также попытался переименовать «делегата», чтобы предотвратить столкновения, как вы предлагаете, но это не имело никакого значения. Когда вы говорите, что мой popover ivar следует более точно набирать - что вы имеете в виду? – Tony

+0

Если SHARRP следит за этим, вы бы так добры, чтобы создать примерный проект (аналогичный тому, который вы сделали для http://stackoverflow.com/questions/5922254/how-to-dismiss-uipopover-from-a- button-in-the-popover), который делает то же самое, но использует Storyboard (т. е. управляет перетаскиванием segue в UIViewController, представление которого будет отображаться внутри Popover). Мой код выше был попыткой реализовать ваш пример, но что-то не так, и использование Storyboard/Segue, по-видимому, является основным отличием. – Tony