简体   繁体   中英

Add close button to UIModalPresentationPageSheet corner

Is there a way to add a button at the corner of an UIModalPresentationPageSheet? I mean, I want to put that Apple-like (x) button at the corner of a Page Sheet, but adding it to the parent view makes it appear behind the Page Sheet (and also impossible to tap) and adding it to the Page Sheet will make part of it hidden, since it's out of the view area.

Is there a solution?

Thanks.

Here's a solution that I use. It's not quite what you describe, which would be neat too, but would be tricky since you'd want the button to be partially out of the view's bounds (as you say, it would have to be a child of the view-controller-view's superview).

My solution is to put a close button in the left-button area of a navigation bar. I do this automagically via a UIViewController class extension. To use it, just call [currentViewController presentAutoModalViewController: modalViewController animated: YES];

@implementation UIViewController (Modal)

- (void) presentAutoModalViewController: (UIViewController *) modalViewController withDismissAction: (SEL) onDismiss animated:(BOOL)animated
{
    UINavigationController* nc = nil;
    if ( NO == [ modalViewController isKindOfClass: [UINavigationController class]] )
    {
        nc = [[[UINavigationController alloc] initWithRootViewController: modalViewController] autorelease];

        [nc setToolbarHidden:YES animated: NO];

        nc.modalPresentationStyle = modalViewController.modalPresentationStyle;

        modalViewController.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop
                                                                                                              target:self 
                                                                                                              action:onDismiss] autorelease];
    }
    else
    {
        nc = (UINavigationController*) modalViewController;

        UIViewController* rootViewController = [nc.viewControllers objectAtIndex: 0];
        rootViewController.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop
                                                                                                              target:self 
                                                                                                              action:onDismiss] autorelease];
    }

    [nc setNavigationBarHidden: NO];
    nc.navigationBar.barStyle = UIBarStyleBlack;
    nc.toolbar.barStyle = self.navigationController.navigationBar.barStyle;

    [self presentModalViewController: nc animated: animated ];
}

- (void) presentAutoModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated
{
    [self presentAutoModalViewController:modalViewController withDismissAction: @selector(autoModalViewControllerDismiss:) animated: animated];
}

- (void) autoModalViewControllerDismiss: (id)sender
{
    [self dismissModalViewControllerAnimated:YES];
}

- (BOOL) isAutoModalViewController
{
    return ( self.navigationController != nil && self.navigationController.parentViewController != nil && self.navigationController.parentViewController.modalViewController == self.navigationController );
}

@end

I found @TomSwift's suggestion very helpful. Here is a version that uses the non-deprecated iOS7 methods and ARC.

@implementation UIViewController (Modal)

- (void)presentAutoModalViewController: (UIViewController *) modalViewController withDismissAction:(SEL) onDismiss animated:(BOOL)animated
{
    UINavigationController* nc = nil;
    if ( NO == [ modalViewController isKindOfClass: [UINavigationController class]] )
    {
        nc = [[UINavigationController alloc] initWithRootViewController: modalViewController];
        [nc setToolbarHidden:YES animated: NO];
        nc.modalPresentationStyle = modalViewController.modalPresentationStyle;

        modalViewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop
                                                                                                              target:self
                                                                                                              action:onDismiss];
    }
    else
    {
        nc = (UINavigationController*) modalViewController;

        UIViewController* rootViewController = [nc.viewControllers objectAtIndex: 0];
        rootViewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop
                                                                                                             target:self
                                                                                                             action:onDismiss];
    }

    [nc setNavigationBarHidden: NO];
    nc.navigationBar.barStyle = UIBarStyleBlack;
    nc.toolbar.barStyle = self.navigationController.navigationBar.barStyle;

    [self presentViewController:nc animated:animated completion:nil];
}

- (void)presentAutoModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated
{
    [self presentAutoModalViewController:modalViewController withDismissAction: @selector(autoModalViewControllerDismiss:) animated: animated];
}

- (void)autoModalViewControllerDismiss: (id)sender
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (BOOL)isAutoModalViewController
{
    return ( self.navigationController != nil && self.navigationController.parentViewController != nil && self.navigationController.parentViewController.presentedViewController == self.navigationController );
}

@end

And I call it like...

MyController *vc = [[MyController alloc] init];
vc.modalPresentationStyle = UIModalPresentationFormSheet;
vc.modalTransitionStyle = UIModalTransitionStyleCoverVertical;   
[self presentAutoModalViewController:info animated:YES];

EDIT: Actually, the first thing I would suggest you do is use a different kind of close button. You can, for example, add a toolbar at the top with a Done button.

If you still want the Apple-style floating X, then try setting properties to make sure it doesn't get hidden or clipped. I would say the better way to do this would be to create a UIButton with a foreground image which is the styled button image, and a background image which fades from the background colour/patterns of the page sheet to a transparent background around the button. It effectively gives you a "floating close button" without having to go outside the bounds of the page sheet.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM