I have a strange issue with layer-backed NSView and it's siblings, some of them are not rendered correctly when added into the existing view hierarchy attached to the rotated superview. Below are the details.
- NSScrollView (layer can be here)
- NSClipView (or here)
- Document View (or even here)
- Some *rotated* subview
- { Problematic sublings }
So, the hierarchy itself is rather simple and common: a scrollview with some document, document subviews represent some content. In my case it's graphics content and it can be rotated. Rotated views can have some additional subviews - various markers, control points and so on and that's where I face strange issues with skewed graphics once I use CALayer for a back-end:
Camera pictures are rendered separately, they are not the part of this view tree, pay attention to the markers and buttons.
As you can see on the image, I have some test views with subviews (just random buttons). Object on the right is rendered correctly, always. According to my tests, each and every NSView with frameRotation between [0, pi/2]
renders OK. Object on the left is rendered
blurry, it looks like caching buffer for this item is too small. It happens when frameRotation is in the [pi/2, pi]
range.
This issue doesn't happen in "real-time rotation". I.e. if I just change the frameRoation of the set-up hierarchy, with each subview on it's place, everything works fine. However, when subling are added to the already rotated object - it bugs and gives this blurred look.
In my application special subview appear when the user clicks on the item, that' the moment when the sibling are added into the superview.
It seems like back-end layer has some caching buffer for the subviews and some of them are computed with the wrong size when the root view is rotated.
[view
setWantsLayer:YES]
to the root views of the hierarchy: scroll view,
clip view, document view, each tme the result was the same. No
hand-made layers, no layer hosts.That's the question, actually. Has anybody faced such issue? Of maybe someone knows the way to force the layer to drop all the caches and renew completely? So far I have only two solutions: to either drop the layers completely (works, but turns of all the eye-candy as well), or re-set the layer calling setWantsLayer:NO
followed by setWantsLayer:YES
. This one has terrible performance.
You've written that you tried "setNeedsDisplay". Are you calling this method from the main thread? In one of my applications nothing happened if I called setNeedsDisplay from another thread. If you want to make sure the display is invalid, then use dispatch like so:
dispatch_async(dispatch_get_main_queue(), ^{
[view setNeedsDisplay:YES];
});
Additionally have a look in your IB inspector. Sometimes layer backed views don't like being mixed with non layer backed views. Make sure, that in the "View Effects Inspector" layer support is turned on for all subviews of your root layer.
(In my program sometimes NSButtons vanished if layer support was turned off)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With