I'm trying to animate a UIVisualEffectsView with a blur effect on top of a UIImageView. Animating the effects view 'in' seems to work, however when animating it 'out' on the first animation frame the effect vanishes to what looks like a 0.5 alpha view.
Is this a bug in iOS8 or am I doing it wrong?
You can play with the example project at https://github.com/mickeyl/iOS-Bug-Example-Projects/tree/master/Animating-UIVisualEffectsView
Here is a preview of what I'm seeing:
Update: Obviously the problem is the height parameter in the new rect. Keeping it works around it. If you then add the effect as subview to the image and clipToBounds, I can get the intended effect. Still I view this as a bug.
This is the response from Apple Developer Relations:
This issue behaves as intended based on the following:
When animating the height 0 -> 300, the presentation layer in the
render server knows its full size so the render server can properly
sample for blur. When returning back to zero height, the presentation
layer now has a height of zero, to which the render server has no way
to sample correctly. So the effect drops but the remaining layers
still animate properly.
Your solution is the correct one. The render server simply cannot
accommodate blur in this scenario.
Please update your bug report to let us know if this is still an issue
for you.
Related
So I'm pretty new to AutoLayout, but more often than not I'm able to hack my views into shape or model off samples on the web.
However, I've created this rather complex view that just doesn't resize no matter what constraints I try.
Here are a few screenshots of what's going on.
The first shot is my Interface Builder layout. It's got a 4-corners kind of thing going on, with a UIImageView in each corner. In the center is a blurred VisualEffectView; it lays on top of the images. The layout was constructed with the parent view at 200x200
The second shot is a successful rendering at 200x200. As you can see, the 4 images load fine (yeah, I know they're a bit stretched, I just haven't handled their scaling code yet). Programmatically, I set the cornerRadius properties of both the parent view and the blurred view to 1/2 their width, so as to make them circular. Also programmatically, I added a label as a subview to the blurred view.
Then it all goes downhill. The third shot is my attempting to render the view at 250x250. The parent view renders well and maintains a circular shape, but just about everything else is wrong.
The most frustrating part is the UIImageViews, which all go haywire and extend their bounds even though I've set them to be equal widths.
The blurred view at least stays centered, but something isn't called which prevents its bounds.width property to be updated, which is what the cornerRadius is based off of.
The label doesn't stay center in the blurred view, despite setting its autoesizingMask to flexible all around.
Here is a snippet of my initialization code, which might be useful.
Any help that you all could provide would be greatly appreciated (even if it just fixes one of the several issues).
P.S. I apologize for the cats pics.
Edit: I achieved the desired result by writing the code manually and ditching Interface Builder and AutoLayout entirely.
So I have a UITextView, and in viewDidLoad I rotate its layer so it appears to be slanted back into the screen (sort of like the Star Wars opening crawl).
The problem is that scrolling is all messed up. Dragging up will scroll for a bit, then jump backward or similar; on the simulator it will even crash sometimes with an error about a coordinate containing NaN.
Similarly, when I try to automatically scroll the UITextView via [UIView animateWithDuration:...] I also get unexpected skips, jerks, etc.
I assume this has something to do with the fact that I've manipulated the layer, but the touch events as well as the animations are registered on the view... Or something like that?
Anyway, I'm pretty stumped.
Are you using constraints to position the text view? There seem to be issues with using transformations and constraints together. A common workaround seems to be to wrap the offending item in another view. The big issues are on iOS7, but some applies to iOS8 as well. This link discusses the issues which may be your issue:
How do I adjust the anchor point of a CALayer, when Auto Layout is being used?
I have successfully started a session on a sublayer but the video looks like this. Do I need to add self.view.layoutIfNeeded() somewhere? If so where can I put it? I've put it in a few different areas but no go. Should I be using something called kCAGravityResize? My goal is to have the video on its own layer filling half screen and then have a tableView layer for graphics text etc filling the other half of the screen. How would I do this?
To debug this you can give the preview layer a background color. This allows you to see where the layer is, and where the video on that layer is.
I don't know your exact view hierarchy but the problem here is often that the view resizes, but the preview layer keeps the same frame.
You can subclass your view and update the preview layer's frame in layoutSublayersOfLayer:.
I seem to have got it working using viewLayer.masksToBounds. The video preview now follows the size I set for the UIImageView.
I have a UIVisualEffectView with a UIBlurEffect effect as a pinned UICollectionViewCell in a UICollectionView.
The blur is masked with an icon so that the icon appears in a subtle shimmery way, responding to whatever it is drawn on top of.
The effect is on top of the collection's background. As it stays pinned and the varying background scrolls underneath, it gently changes to reflect the background and looks very nice.
However, except for the collections's scrolling background, most content is drawn in front of the blur effect. This is necessary because that other content is more important and shouldn't be obscured.
Even though it is behind the more important content, I'd like the effect view to reflect the content that is scrolling in front of it. Any suggestions for how this might be made to work?
Ideas:
Could I grab a chunk from the previously drawn frame and draw this under the effect view? How would I do that?
Could I render the whole collection view, apply the blur, and then render everything that should be on top of the blur a second time? How can I make that efficient?!
Thanks.
I went with a slightly refined version of the second option.
I added some duplicate cells to the collection view that are rendered behind the blur, and then also in front. I've only done this for one of my cell types with lots of colour in it. It works pretty well.
If you have a better approach I'll happily assign you the correct answer.
A am using the brilliant StackBlur class with in my project which works fine however I am trying to create a similar effect to the Yahoo Weather App in which the image blurs according to the scroll value. I have managed to achieve it using the scrollViewDidScroll method however the effect is slow and laggy.
What is the best way yo resolve this? Storing the image to the Cache is the only thing I can think of.
Thanks
UPDATE
I simply created two UIImageViews one with the blur and then set the alpha to zero and increased it with the content offset off the scrollview.
You don't need to blur every time when scrollViewDidScroll called. Instead, you need a blurred imageView with the final blur effect and none blurred imageView placed below the blurred one. Change view.alpha of blurred imageView from 0.0 to 1.0 will get this effect without extra cost.
Try DKLiveBlur to show live effect of yahoo blur.