I need to implement a UINavigationBar with a custom design, the back image needs to be changed, all the colors need to be changed and the height needs to be changed.
I know all that is possible, but I also need to change the blur effect. It needs to be a lighter blur. Is there a way of doing this without going into private APIs?
Edit: a picture of what it is supposed to look like (I know the status bar is pixelated, ignore it):
UIVisualEffectView will add translucency and blur effect on iOS 8+ views.
There are three blur UIBlurEffectStyles available.
- (void)addBlurEffect{
CGRect bounds = self.navigationController.navigationBar.bounds;
UIVisualEffectView *visualEffectView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]];
visualEffectView.frame = bounds;
visualEffectView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.navigationController.navigationBar addSubview:visualEffectView];
self.navigationController.navigationBar.backgroundColor = [UIColor clearColor];
[self.navigationController.navigationBar sendSubviewToBack:visualEffectView];
}
For more information of UIVisualEffectView, check this question on SO.
*************** EDIT FOR iOS 7 ***************
Nicklockwood's FXBlurView came into picture for rescue for iOS5, iOS6, iOS7.
I create a sample project for you which has the desired dynamic blur effect on navigation bar for iOS7. Follow the below guide to use into your project.
Look into AppDelegate.m
Here I add the background image to the navigation bar. You can update the image in any viewcontroller to achieve the dynamic blur background image on navigation bar.
There are few FXblurview properties like blurRadius, iterations, tintColor; which you must read here.
Installation Guide:- https://github.com/nicklockwood/FXBlurView?source=c#installation
Full source code of FXBlurView-master can found here.
Related
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.
Let me explain my situation first. I set the UINavigationBar color in my appDelegate Like:
[[UINavigationBar appearance] setBarTintColor:[UIColor colorWithRed:255.0f/255.0f green:87.0f/255.0f blue:10.0f/255.0f alpha:1]];
Now in my some viewController the translucent of UINavigationBar set as YES.
self.navigationController.navigationBar.translucent = YES;
That's why there is a shade over my UINavigationBar. It wasn't showing the exact color. As a solution, I set translucent from YES to NO. It is showing the exact color now, But I am facing that some of my view completely gone from my interface. Here, let me tell you one thing that, so many of views here, is positioned by programmatically, so I am afraid I can't just move every of my viewControllers view 64 px high. Just wondering is there any solution to solve the thing. I try with opaque, but no luck. If any one understand my problem please share the solution if you have. Thanks a lot in advance.
From iOS7 if you use a translucent bar ( in UINavigationController or UITabbarController) the hosted view controller has as default behavior to extend under them. If you say to set the bar as translucent the color of it it will be a combination of the view under it and bat color. That is normal and the only way is to set translucency to no or apply a background image to navigation bar.
Applying frames manually will lead to unexpected result under auto layout, you must use constraints.
[UPDATE]
To create a background image from a solid color you can use that method, the image is 1px square, but there is no problem because it can be stretched or tiled to cover the entire area:
+ (UIImage *) imageWithColor:(UIColor*) color {
CGRect rect = CGRectMake(0, 0, 1, 1);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillRect(context, rect);
UIImage *colorImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return colorImage;
}
If you see and extra gap is probably because you have also set automaticallyAdjustScrollViewInset to YES, try setting it NO. This property add and extra inset to your view or your vfirst view subview if it inherits from a UIScrollView
Its late, but i face same issue, and i resolved it by making UINavigationbar none on Viewcontroller in storyboard, and resized the view to start from 0,0
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.
I want to have my navigation bar clear in iOS 7. I know this question has been asked before, but I cannot find an answer to the specific problem that I am having. I set my navigation bar clear in my App Delegate using this code:
UINavigationBar *navigationBarAppearance = [UINavigationBar appearance];
navigationBarAppearance.backgroundColor = [UIColor clearColor];
[navigationBarAppearance setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault];
navigationBarAppearance.shadowImage = [[UIImage alloc] init];
That works fine, my first navigation bar is clear. Then when I select a button and push a new view controller it gets a slight alpha increase on it. Looks like black with about 20% alpha. See picture here:
Then when i press the back button, the first view has the same slight alpha increase affect on it.
I have commented out ALL references to navigation bar in the second view controller to make sure I'm not accidentally changing something. I checked for differences in IB between the first and second view controllers and can't find anything there either. Tearing my hair out!
try setting the translucent property to YES in viewDidAppear
navigationBarAppearance.translucent = YES;
try this !
navigationBarAppearance.layer.backgroundColor = [UIColor clearColor].CGColor;
As expected I was missing something in the code!
The view controller inherited from a custom view controller class that was setting an alpha onto the navigation bar.
The iOS7 Facebook App has a right side menu that can be shown by swiping right to left or clicking on the upper right button. When this menu is opened the there is a color transition in the entire status bar from blue to black and vice-versa when closed.
This image shows both status bar side-to-side
This looks like a very good solution for iOS Apps with side menus.
Any ideas or ways about how to accomplish this?
I am currently using JASidePanels.
Thanks!
I managed to find a very simple, elegant way to do this, that mimics the Facebook app functionality perfectly.
Here's my approach:
Create view with status bar frame
Set view background color to black, opacity to 0
Add view as subview to any root view (you need a view that will cover both the center view and the menus, so that it won't be confined to any single view - a good option for this is the container view controller used by your menu controller implementation)
Set view's opacity in your menu controller implementation's menu animation method
Here's my specific implementation, using MMDrawerController:
I subclassed MMDrawerController (I actually already had a subclass for using MMDrawerController with storyboards), and added this code to the class's init method:
// Setup view behind status bar for fading during menu drawer animations
if (OSVersionIsAtLeastiOS7()) {
self.statusBarView = [[UIView alloc] initWithFrame:[[UIApplication sharedApplication] statusBarFrame]];
[self.statusBarView setBackgroundColor:[UIColor blackColor]];
[self.statusBarView setAlpha:0.0];
[self.view addSubview:self.statusBarView];
}
// Setup drawer animations
__weak __typeof(&*self) weakSelf = self; // Capture self weakly
[self setDrawerVisualStateBlock:^(MMDrawerController *drawerController, MMDrawerSide drawerSide, CGFloat percentVisible) {
MMDrawerControllerDrawerVisualStateBlock block;
block = (drawerSide == MMDrawerSideLeft) ? [MMDrawerVisualState parallaxVisualStateBlockWithParallaxFactor:15.0] : nil; // Right side animation : Left side animation
if(block){
block(drawerController, drawerSide, percentVisible);
}
[weakSelf.statusBarView setAlpha:percentVisible]; // THIS IS THE RELEVANT CODE
}];
I also added self.statusBarView as a private property.
The first section of code creates a view, configures it, and adds it as a subview of the MMDrawerController subclass's view. The OSVersionIsAtLeastiOS7() method is a custom method that simplifies the check to see if the device is running iOS 7 (if it isn't, your custom view will show up below the status bar, which you don't want).
The second section of code is MMDrawerController's setDrawerVisualStateBlock method, which sets the animations code to be performed when a menu is being opened and closed. The first few lines of code are boilerplate code that sets one of the prebuilt animations blocks to each menu (I wanted parallax on the left, but nothing on the right). The relevant code is the last line of the block: [weakSelf.statusBarView setAlpha:percentVisible];, which sets the status bar view's opacity to match the percentage that the menu is currently open. This allows for the smooth cross animation you see in the Facebook app. You'll also notice I've assigned self to a variable weakSelf, so as to avoid the "retain cycle" compiler warning.
This is my specific approach using MMDrawerController and a subclass, which I did more for convenience because I already had the subclass in place, than because it is necessarily the best approach or the only way to do it. It could probably be implemented in several other ways, using MMDrawerController without a subclass, or using any other side-drawer menu implementation.
The ending result is a smooth fading to black animation behind the status bar, exactly as you see in the new Facebook app.
I've been trying to accomplish the same thing. The method I am using to do this is based on the following concepts:
A background image with a height of 64 points will fill both the
UINavigationBar and the UIStatusBar.
A background image with a height of 44 points will fill the UINavigationBar and leave the
UIStatusBar black.
You can add an subview to the top of the current navigationController's view and it will sit underneath the UIStatusBar.
So, first, you need to create two images with your desired UINavigationBar look:
A 640x128px image to cover navigation bar and status bar (ImageA)
And a 640x88px image to cover the navigation bar but leave the status bar black (ImageB).
In the application:didFinishLaunchingWithOptions: method, set the background of your UINavigationBar with ImageA with [[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"ImageA.png"] forBarMetrics:UIBarMetricsDefault];
When the side menu starts to open, you are going to want switch the UINavigationBar so it uses ImageB and create a view which you will add underneath the UIStatusBar. Here is some sample code for doing just that:
// Add a property for your "temporary status bar" view
#property (nonatomic, strong) UIView *temporaryStatusBar;
And in the code where the side menu starts to open:
// Create a temporary status bar overlay
self.temporaryStatusBar = [[UIView alloc] initWithFrame:[[UIApplication sharedApplication] statusBarFrame]];
self.temporaryStatusBar.backgroundColor = [UIColor yourColor];
[self.navigationController.view addSubview:self.temporaryStatusBar];
// Update both the current display of the navigationBar and the default appearance values
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"imageB.png"] forBarMetrics:UIBarMetricsDefault];
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"imageB.png"] forBarMetrics:UIBarMetricsDefault];
[self.navigationController.navigationBar setNeedsDisplay];
As the side menu animates open, or as the user pans the menu, all you need to do then is adjust the alpha level of the UIStatusBar overlay. When the side menu is fully open, the UINavigationBar should have ImageB as its background image and the UIStatusBar overlay should have an alpha of 0. When the side menu closes, you'll want to replace the UINavigationBar background with ImageA and remove the UIStatusBar overlay.
Let me know if this works for you!
You can use this awesome slide menu library
https://github.com/arturdev/AMSlideMenu
In this demo project you can see how to do that by writing 4 lines of code.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Setting navigation's bar tint color
self.navigationController.navigationBar.barTintColor = [UIColor colorWithHex:#"#365491" alpha:1];
// Making view with same color that navigation bar
UIView *statusBarView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 20)];
statusBarView.backgroundColor = [UIColor colorWithHex:#"#365491" alpha:1];
// Replace status bar view with created view and do magic :)
[[self mainSlideMenu] fixStatusBarWithView:statusBarView];
}