Hi Rincewind (hope you're still listening),
(TL;DR: Read underlined question.)
I understand the description and subtleties of the offscreen rendering of UIVisualEffectViews, and I've implemented our effects to work in iOS 10 with your instructions here vis-à-vis the maskView property. However, this implementation is failing on iOS 9. Specifically, on iOS 9 the views are failing to render at all, as if they had their hidden property set to true.
This has 'nerd-sniped' a large portion of our iOS team here at Tulip, and we just can't figure it out. I've also recently watched the WWDC session "What's New in UIKit Dynamics and Visual Effects" and that hasn't helped me with this one. None of the posts here reference both iOS 9 and 10 and the same time, and so we're beginning to wonder if it's just not possible. Is it possible to have a single code-path implementation of a visual effect view that will work for both iOS 9 and iOS 10?
Our requirements include that only two corners be rounded, which means that we cannot simply use the cornerRadius & clipsToBounds method. Our requirements also include supporting both iOS 9 & 10 concurrently, and we hate divergent code paths as a solution to "well, this way used to work" problems.
Here is the pseudo code for our issue:
@implementation UIView (RoundedMask)
- (void)roundCorners:(UIRectCorner)corners withRadius:(CGFloat)radius {
CGSize radii = CGSizeMake(radius, radius);
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds
byRoundingCorners:corners
cornerRadii:radii];
CAShapeLayer *layer = [CAShapeLayer layer]; // Fill colour defaults to opaque black
layer.path = path.CGPath;
UIView *view = [[UIView alloc] initWithFrame:self.bounds]; // Background colour defaults to transparent.
[view.layer addSublayer:layer]
self.maskView = view; // Masks self by removing pixels where maskView is transparent.
}
@end
(This method is sometimes used on non-effect views as well. We are aware of the "but what if your view resizes?" issue.)
If I break on line 15 and use the debugger QuickLook feature on the view variable, I do see a black opaque rectangle with the appropriate corners rounded and a transparent background. If I replace line 13 with the following three lines:
view.backgroundColor = [UIColor blackColor];
view.layer.cornerRadius = radius;
view.clipsToBounds = YES;
… then the effect is properly masked and composited on both iOS versions, but of course fails our design requirement of partially-rounded rectangles. Previously, lines 12-14 were omitted, and line 15 read:
self.layer.mask = layer;
… but of course this does not composite properly on iOS 10.
This method is invoked from a method that is invoked in a viewDidLoad method, but even if I move that invocation to the viewWillAppear: method as you recommend elsewhere (to get around a β bug) I get the same behaviour on iOS 9.
Also, you mentioned subclassing UIView to have a custom layerClass, and I thought perhaps there was a remote possibility that maskView does not support sublayers on iOS 9. So: I tried creating a subview, 'UIShapeView', with CAShapeLayer as its layerClass and with forwarding accessors for the path property. Changing line 12 to create one of these views and 13 to set its path (bypassing lines 9 & 10) was also futile.
When I use the View Hierarchy Debugger, and inspect _whatsWrongWithThisEffect of the non-visible view in iOS 9, I get the empty string. What's more, the content of the visual effect view is visible in that debugger, and all the way up and down the hierarchy (relative to the visual effect view) alpha is set to 1 and hidden is set to Off (clipsToBounds is set to Off all the way up the hierarchy (including the visual effect view itself), but subviews of the visual effect view do have clipsToBounds set to On).
The specific systems I'm getting these results from are both iPad minis running iOS 9.3.5 and iOS 10.2.1, and the app is built with Xcode 8.2.1 on macOS 10.12.3.
I am more that happy to investigate more on your prompting, or to send you screenshots via private message, but I think I've been as thorough as I possibly can. We'd sincerely appreciate any guidance you can give us on this issue, and we thank you for your time on this forum (this thread alone has been indispensable).