Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove the inner shadow that UIPopoverController creates

I am creating a custom layout of the popover that iOS provides. I have subclassed the UIPopoverBackgroundView and got it to draw the background for my popover correctly. My problem is now that UIPopoverController creates an inner shadow on the popover affecting the contentViewController of the popover. I want to remove this inner shadow, so only the content of my contentViewController is displayed.

This is how the popover currently looks, with a UILabel to demonstrate the effect on the contentViewController.

popover

Is there any way to remove this inner shadow?

like image 884
Sorig Avatar asked Jan 05 '12 15:01

Sorig


2 Answers

Support for this was added in ios6.0 with the following call:

+ (BOOL)wantsDefaultContentAppearance

Link to documentation: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIPopoverBackgroundView_class/Reference/Reference.html

like image 177
kajham Avatar answered Nov 21 '22 16:11

kajham


Since there is no elegant way to do this and since I do not want to rewrite the entire UIPopoverController just to do this, I've created a simple hack that removes the inner shadow on the popover by traversing the UIView structure. The hack is a category on UIPopoverController and I just put it in the files for my subclass of UIPopoverBackgroundView. So here's the code:

@interface UIPopoverController(removeInnerShadow)

- (void)removeInnerShadow;
- (void)presentPopoverWithoutInnerShadowFromRect:(CGRect)rect 
                                          inView:(UIView *)view 
                        permittedArrowDirections:(UIPopoverArrowDirection)direction 
                                        animated:(BOOL)animated;

- (void)presentPopoverWithoutInnerShadowFromBarButtonItem:(UIBarButtonItem *)item 
                                 permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections 
                                                 animated:(BOOL)animated;

@end

@implementation UIPopoverController(removeInnerShadow)

- (void)presentPopoverWithoutInnerShadowFromRect:(CGRect)rect inView:(UIView *)view permittedArrowDirections:(UIPopoverArrowDirection)direction animated:(BOOL)animated 
{
    [self presentPopoverFromRect:rect inView:view permittedArrowDirections:direction animated:animated];
    [self removeInnerShadow];
}

- (void)presentPopoverWithoutInnerShadowFromBarButtonItem:(UIBarButtonItem *)item 
                                 permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections 
                                                 animated:(BOOL)animated
{
    [self presentPopoverFromBarButtonItem:item permittedArrowDirections:arrowDirections animated:animated];
    [self removeInnerShadow];
}

- (void)removeInnerShadow
{
    UIWindow *window = [[[UIApplication sharedApplication] delegate] window];

    for (UIView *windowSubView in window.subviews)
    {
        if ([NSStringFromClass([windowSubView class]) isEqualToString:@"UIDimmingView"])
        {
            for (UIView *dimmingViewSubviews in windowSubView.subviews)
            {
                for (UIView *popoverSubview in dimmingViewSubviews.subviews)
                {
                    if([NSStringFromClass([popoverSubview class]) isEqualToString:@"UIView"]) 
                    {
                        for (UIView *subviewA in popoverSubview.subviews)
                        {
                            if ([NSStringFromClass([subviewA class]) isEqualToString:@"UILayoutContainerView"])
                            {
                                subviewA.layer.cornerRadius = 0;
                            }

                            for (UIView *subviewB in subviewA.subviews)
                            {
                                if ([NSStringFromClass([subviewB class]) isEqualToString:@"UIImageView"] )
                                {
                                    [subviewB removeFromSuperview];
                                }
                            }
                        }
                    }
                }
            }
        } 
    }
}

@end

When I want to display my popover I just call the presentPopoverWithoutInnerShadowFromRect: and presentPopoverWithoutInnerShadowFromBarButtonItem: methods instead of the standard ones. NOTE: Remember to #import <QuartzCore/QuartzCore.h> for the code to work

like image 40
Sorig Avatar answered Nov 21 '22 16:11

Sorig