4

I'm using a stock UISplitViewController with out-of-the-box Master and Detail view controllers. In a storyboard, I've added a UIImageView to the Detail controller set to effectively fill the view with a single image.

In the Master controller, I've used the following to blur the background of that controller:

// In viewDidLoad

self.tableView.backgroundColor = [UIColor clearColor];
    UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
    UIVisualEffectView *visualEffectView = [[UIVisualEffectView alloc]
                                            initWithEffect:blurEffect];
    self.tableView.backgroundView = visualEffectView;
    self.tableView.separatorEffect = [UIVibrancyEffect effectForBlurEffect:blurEffect];

When the Master controller appears above the Detail controller, note how the edges of the Master controller have a dark shadow around the inner edges.

How can these "shadows" be removed to instead render a uniform blur?

Split View Controller

More Details

UIPopoverSlidingChromeView

Debugging the view hierarchy in IB reveals a (private?) view called _UIPopoverSlidingChromeView. It has an inset grey frame, and it's definitely what's responsible for the non-uniform blur appearance.

Disabling the blur view altogether and just leaving self.tableview.backgroundColor = [UIColor clearColor] shows _UIPopoverSlidingChromeView's grey frame. It looks like this:

Rendered UIPopoverSlidingChromeView

Any thoughts on how to avoid _UIPopoverSlidingChromeView when using UISplitViewController?

David H
  • 39,114
  • 12
  • 86
  • 125
Chris Droukas
  • 2,908
  • 1
  • 21
  • 24
  • 1
    Excellent question! This same view is wrecking havoc when you try to programmatically close a primary view in "PrimaryOverlay" mode on the iPhone 6 Plus. – David H Dec 08 '15 at 19:13
  • 1
    You should really award the answer to trans below. If you are still interested in this, I'm working on a solution to hide that chrome view for iPhones using PrimaryOverlay - it animates horridly on the phone - no idea why its broken there but works perfectly on the iPad. – David H Dec 08 '15 at 19:43
  • 1
    @DavidH done! There's an element of fragility to it, but it suffices for now. – Chris Droukas Dec 08 '15 at 19:44
  • 1
    Try just setting the view.alpha to 0 - that does it too, less specific than changing a border of the underlying layer. Once I get my phone code working, I was considering using a blur view under it, so this question solved what would have been a future issue for me! BTW, superb question - details and all! And regarding "fragility" - if you find the view, then you make the UI perfect - if you don't find it, well then nothing bad happens. – David H Dec 08 '15 at 19:48
  • 1
    Sorry to beat this to death, last post. But if you see the reverse engineered class description, its a pretty sophisticated class. I think just hiding it one way or the other is for sure a better way to solve the problem: https://github.com/EthanArbuckle/IOS-7-Headers/blob/master/Frameworks/UIKit.framework/_UIPopoverSlidingChromeView.h – David H Dec 08 '15 at 19:52
  • 1
    @DavidH props for revisiting this question — it's over a year old! – Chris Droukas Dec 08 '15 at 19:55
  • 1
    Hah - one more comment - here is my Q&A based on this one: http://stackoverflow.com/q/34167266/1633251 – David H Dec 08 '15 at 22:45

2 Answers2

3
    //как убрать дурацкий прямоугольник при прозрачном фоне maser окна в режиме UISplitViewControllerDisplayModeOverlay
    CALayer* v_1 =  self.view.superview.superview.superview.layer.sublayers[0];
    CALayer* v_2=v_1.sublayers[0];
    v_2.borderWidth=0;
trans
  • 31
  • 2
  • 1
    So this does... what? – Max Leske Dec 14 '14 at 15:57
  • 1
    Without testing, it looks like it's running up the view chain to find the offending `CALayer` and eliminating the border. This looks promising. – Chris Droukas Dec 15 '14 at 18:36
  • 2
    While this may work today, you don't own this part of the view hierarchy and it is not guaranteed to work tomorrow. If Apple changes how they build the views for their framework controllers, in the best case the visual you want disappears in a future version of iOS. In the worst case, your app starts crashing. In my experience, you're better off building a custom class if Apple's classes don't do exactly what you want. It's more work, but better over the long term. – Steve Madsen Jun 23 '15 at 14:00
  • 1
    Perhaps a better way to do this is to set the view's alpha to zero. – David H Dec 08 '15 at 19:19
1

The problem is that it is a private class that you can't test against.

Fortunately _UIPopoverSlidingChromeView is the subclass of UIPopoverBackgroundView that is public (because in regular popover implementation flow client may customize the popover background chrome by providing a class which subclasses UIPopoverBackgroundView).

for (UIView *subview in self.viewController.view.superview.superview.subviews) {
    if ([subview isKindOfClass:[UIPopoverBackgroundView class]]) {
        subview.alpha = 0.0;
    }
}

This should hide the _UIPopoverSlidingChromeView.

Jakub Truhlář
  • 15,319
  • 7
  • 65
  • 73