Blur view on previous VC in the navigation stack - ios

I have VC 1. From it I present VC 2. The VC 2 have bottom part with tableView and top part is clear, and thought it I can see VC 1. It works correctly.
Now I need to add blur effect to top clear area of VC 2.
I made this using UIVisualEffect
My code:
UIVisualEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
UIVisualEffectView *blurView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
It works, but I need to change our color to some custom. There si not such capabilities in UIVisualEffect. So I need some other solution.
How can I do it?
I tried to make it with FXBlur, but then problem here I guess in that I can not blur view from VC 1 adding blur in VC 2.
Now I think that I can make screenshot of VC 1's view, send it to VC 2, set it to imageView and then blur imageView with custom color.
But I think that status bar will not display actual time as it will be an image. How can I do this blur, maybe there is more smart solution? Because I do not like that I need send screenshot through ViewControllers

Related

swift - How to blur the background of UIPickerView? [duplicate]

I am displaying a UIPickerView when tapping on a UITableViewCell. I am trying to add a UIVisualEffectView to the pickerView to give it a blurred background. What I'm trying to get is this:
https://www.evernote.com/shard/s111/sh/645d307f-c597-4dfa-890f-9404ed297e71/fd738fdf15cd956fcfa917e4311bfd1b
What I'm actually getting is this:
https://www.evernote.com/shard/s111/sh/27440e85-2181-49e1-89e0-4b57e0ce3783/e6e2abae0edfb705e915b03e1b37e008
Here is the code I'm using to create the blur and attach it to the picker:
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
[blurEffectView setFrame:_myPicker.frame];
[_myPicker addSubview:blurEffectView];
[_myPicker sendSubviewToBack:blurEffectView];
Notice that even with the call to sendSubviewToBack, this ends up putting the blur in front of the option wheel. If I look carefully when I scroll the view, I can see the options moving behind the blur.
How do I get the blur properly in the background and the option wheel on top?
As you do not know the exact view hierarchy of a UIPickerView I would simply recommend to give your pickerView clearColor as backgroundColor and to put the picker view as subview of your blurEffectView. This would be the right way to do this.

Blurring a UIPickerView's background

I am displaying a UIPickerView when tapping on a UITableViewCell. I am trying to add a UIVisualEffectView to the pickerView to give it a blurred background. What I'm trying to get is this:
https://www.evernote.com/shard/s111/sh/645d307f-c597-4dfa-890f-9404ed297e71/fd738fdf15cd956fcfa917e4311bfd1b
What I'm actually getting is this:
https://www.evernote.com/shard/s111/sh/27440e85-2181-49e1-89e0-4b57e0ce3783/e6e2abae0edfb705e915b03e1b37e008
Here is the code I'm using to create the blur and attach it to the picker:
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
[blurEffectView setFrame:_myPicker.frame];
[_myPicker addSubview:blurEffectView];
[_myPicker sendSubviewToBack:blurEffectView];
Notice that even with the call to sendSubviewToBack, this ends up putting the blur in front of the option wheel. If I look carefully when I scroll the view, I can see the options moving behind the blur.
How do I get the blur properly in the background and the option wheel on top?
As you do not know the exact view hierarchy of a UIPickerView I would simply recommend to give your pickerView clearColor as backgroundColor and to put the picker view as subview of your blurEffectView. This would be the right way to do this.

UIVisualEffectView on UITableView background

I am creating a UITableViewController (at the root of a UINavigationController) and presenting this modally on top of another view controller. I have it working to an extent, such that when the view loads and viewDidAppear is called, the visual effect looks good. But right after viewDidAppear, the visual effect goes away and the tableview has a white background.
In my presented UITableViewController, I added this in viewDidLoad:
if (NSClassFromString(#"UIVisualEffectView") && !UIAccessibilityIsReduceTransparencyEnabled()) {
self.tableView.backgroundColor = [UIColor clearColor];
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
[blurEffectView setFrame:self.tableView.frame];
self.blurView = blurEffectView;
self.tableView.backgroundView = self.blurView;
}
I also implement this, to make sure the cells have a clear background:
- (void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
if (NSClassFromString(#"UIVisualEffectView") ) {
cell.backgroundColor = [UIColor clearColor];
}
}
I also set the cell.backgroundColor = [UIColor clearColor] in tableView's cellForRowAtIndexPath: but that doesn't help either.
Again, I get the correct effect when the view loads, but it loses the blur background as soon as it appears on screen. Any ideas what might be going wrong? I have also tried to retain the blueEffectView as a property in my view controller, but no luck
Are you using Storyboards?
Select the view controller that's used modally (or if it's wrapped in another VC, select the wrapper) and set the Presentation combo box to "Over Full Screen" or "Over Current Context". (I don't actually know what the difference is, they both seem to do the same thing.)
After doing that, your blur effect should Just Work™. Also, I think this is new in iOS 8, I haven't tested this in iOS 7 yet.
The problem is, when you present a view controller modally with the default settings, once it has finished taking over the screen, the underlying view controller seems to be essentially erased. This is why your blur effect looks great until the presentation animation completes - the underlying view vanishes.
To implement the desired behavior, you'll need to change the segue presentation style to something that will preserve the underlying view controller, like Over Full Screen instead of the default Full Screen.
Note that when you dismiss this modal presentation, viewDidAppear will not be called on the presenting view controller, because it's now always visible. That can bite you if you were relying on that method to perform any function upon dismissal.

Blurred Navigation Bar with same background as UITableView

I am trying to achieve a similar effect to that of the Notes app on iOS in that I have a tableView with a background image and I want the navigation bar to have the same background image but without the text from the tableView overlapping.
Here is the tableView scrolled. As you can see, the text of the tableView overlaps that of the status bar and navigation bar. That is why I want the blur effect on the navigation bar.
In iOS8 there is a new UIView subclass called UIVisualEffectView.
You instantiate it with...
UIVisualEffectView *blurView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]; // other styles available
or...
UIVisualEffectView *blurView = [[UIVisualEffectView alloc] initWithEffect:[UIVibrancyEffect notificationCenterVibrancyEffect]; // other styles available
You then can do one of two things.
Either add this in front of the views you want to show through. (Not a sub view but in front of the content).
Or you can take a view and set it as the contentView of the visualEffectView.
This will then automatically add the effect to the content. It even updates when the content is updated so if you have something animating behind it it will show the blurred animation for you.

UINavigationController pushViewController pauses/freezes midway through

I am pushing a view controller via:
[self.navigationController pushViewController:[[UIViewController alloc] init] animated:YES];
But the animation lags/pauses a for half a second mid way through. The animation is not complete. Here's the gif;
With out more detail I can think of 2 possible problem with that.
Is there Shadow added in code to the view that will be covered by the new ViewController. If it is the case, use ShadowPath or an translucent view instead (the property Shadow is expensive while animating, been there done that)
Is the backgroundColor of new ViewController "clearColor" ? I've seen strange rendering problem with that kind of thing.
Try:
UIViewController *vc = [[UIViewController alloc] init];
vc.view.backgroundColor = [UIColor whiteColor];
[self.navigationController pushViewController:vc animated:YES];
That is the 2 possible problems I can think of the top of my head with so few detail.
Never rely on the default background color, it has change with iOS version and is not consistant across controls and can even be different if the view is created in code or from a Xib (in the same iOS version).
In app delegate, set your window's background color to white.
window?.backgroundColor = .white
Also in the the pushed view controller, set its view to white.
view.backgroundColor = .white
I experienced the same issue when programmatically embedding my view controller in a UINavigationController.
While setting the background color as suggested by VinceBurn solved the pausing, it made the entire animation white, fading in the actual content only when the animation finished.
For me the problem was solved by making sure the content was correctly sized in -viewDidLoad.

Resources