问题 故事板:使用委托/协议方法解除Popover


我读了  关于这一点的东西,虽然大多数似乎是关于非故事板的方法,但我认为我拼凑了一些并弄清楚了。但是,以下代码不会导致我的popover被解雇。 Popover中的dismissPopoverButtonPressed按钮执行但委托中的dismissPopover方法中的断点永远不会发生。非常感谢有人密切关注代码以发现错误。

谢谢

在下面,NewGameViewController包含一个UIButton。按此按钮将导致Popover Segue以及随后显示包含PopViewController UIView的弹出窗口。

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];
}

13045
2018-06-10 06:00


起源



答案:


当从故事板segue链接到弹出控制器时, popoverController segue的属性是指标准的UIPopoverController。这个控制器本身有一个属性, contentViewController,代表实际在弹出窗口中呈现的视图控制器,在您的情况下 PopViewController

所以,你当前的代码将自己设置为popover控制器的委托,当它真的需要将自己设置为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;
    }
}

13
2018-06-10 06:41



谢谢。我必须承认,我实现了这个代码并没有完全理解逻辑,但我记得读过关于必须显式声明协议和委托的多个注释,以便可以在生成它的VC中处理Popover事件。当然,根据是否在代码中通过Storyboard显式创建Popover,方法似乎有所不同。话虽如此,我对上述情况仍然不了解。 - Tony
我也尝试重命名'委托'以防止你提出的冲突,但它没有任何区别。当你说我的popover ivar应该更具体地输入 - 你的意思是什么? - Tony
如果SHARRP正在观察这个,你会非常善良地创建一个示例项目(类似于你所做的那个) stackoverflow.com/questions/5922254/...)它使用Storyboard做同样的事情(即,控制 - 拖动一个segue到UIViewController,其视图将出现在Popover内)。我上面的代码试图实现你的例子,但有些事情是不对的,故事板/ Segue的使用似乎是主要的区别。 - Tony
对不起,我再次查看了您的问题,之前的回答是错误的。请看我编辑过的,希望能为您提供更多解释和工作解决方案! - jrturton
jturton - 宾果游戏。非常感谢。解决了我的问题。 - Tony


答案:


当从故事板segue链接到弹出控制器时, popoverController segue的属性是指标准的UIPopoverController。这个控制器本身有一个属性, contentViewController,代表实际在弹出窗口中呈现的视图控制器,在您的情况下 PopViewController

所以,你当前的代码将自己设置为popover控制器的委托,当它真的需要将自己设置为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;
    }
}

13
2018-06-10 06:41



谢谢。我必须承认,我实现了这个代码并没有完全理解逻辑,但我记得读过关于必须显式声明协议和委托的多个注释,以便可以在生成它的VC中处理Popover事件。当然,根据是否在代码中通过Storyboard显式创建Popover,方法似乎有所不同。话虽如此,我对上述情况仍然不了解。 - Tony
我也尝试重命名'委托'以防止你提出的冲突,但它没有任何区别。当你说我的popover ivar应该更具体地输入 - 你的意思是什么? - Tony
如果SHARRP正在观察这个,你会非常善良地创建一个示例项目(类似于你所做的那个) stackoverflow.com/questions/5922254/...)它使用Storyboard做同样的事情(即,控制 - 拖动一个segue到UIViewController,其视图将出现在Popover内)。我上面的代码试图实现你的例子,但有些事情是不对的,故事板/ Segue的使用似乎是主要的区别。 - Tony
对不起,我再次查看了您的问题,之前的回答是错误的。请看我编辑过的,希望能为您提供更多解释和工作解决方案! - jrturton
jturton - 宾果游戏。非常感谢。解决了我的问题。 - Tony