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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10966677/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 00:33:04  来源:igfitidea点击:

Storyboard: Dismissing Popover using delegate/protocol method

xcodeuibuttonstoryboardpopover

提问by Tony

I've read tonsof stuff on this and while most seems to be in regards to the non-storyboard approach, I thought I had pieced bits together and figured it out. However, the following code does not result in my popover being dismissed. The dismissPopoverButtonPressed button in the Popover executes but a breakpoint in the dismissPopover method in the delegate never hits. Would very much appreciate someone casting an eye over the code to spot mistakes.

我已经阅读了大量关于此的内容,虽然大多数似乎与非故事板方法有关,但我认为我已经拼凑起来并弄清楚了。但是,以下代码不会导致我的弹出窗口被关闭。Popover 中的dismissPopoverButtonPressed 按钮会执行,但委托中dismissPopover 方法中的断点从未命中。非常感谢有人关注代码以发现错误。

Thanks

谢谢

In the following, NewGameViewController contains a UIButton. Pressing this results in the Popover Segue and subsequent display of the popover containing the PopViewController UIView.

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

NewGameViewController.h

新游戏视图控制器.h

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

NewGameViewController.m

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

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

PopViewController.m

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

回答by jrturton

When linking to a popover controller from a storyboard segue, the popoverControllerproperty of the segue refers to a standard UIPopoverController. This controller itself has a property, contentViewController, which will represent the view controller that is actually being presented within the popover, in your case the PopViewController.

当从 storyboard segue 链接到 popover 控制器时,segue 的popoverController属性指的是标准的 UIPopoverController。这个控制器本身有一个属性,contentViewController,它代表在弹出窗口中实际呈现的视图控制器,在你的例子中是PopViewController.

So, your current code is setting itself as the delegate of the popover controller, when it really needs to be setting itself as the delegate of the popover's contentview controller.

因此,您当前的代码将自己设置为 popover 控制器的委托,当它确实需要将自己设置为 popover内容视图控制器的委托时。

You still need to keep a reference to the popover controller around, to dismiss, so keep your existing code, but make the following change:

您仍然需要保留对 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;
    }
}