Add image between status bar and navigation bar - ios

I am trying to add an image between the status bar and navigation bar in IOS. Is this possible? Can you please guide me how this can be achieved?
Basically I am trying to achieve something like this:

Exactly I don't know, is it possible or not ? But I have an idea such like,
You need to create custom navigationBar for do this you need to hide your navigationBar of your rootView controller when it created.
EX -
self.rootNavigationController.navigationBarHidden = YES;
Then at first top add your custom image with UIImageView with it's specific size, and then after add your custom UINavigationBar (It is UIImageView/UIView OR whatever) with 2 buttons.

you can use a UIImageView an set its image as per below
- (void) viewDidLoad {
topImage = [[UIIImageView alloc] initWithFrame:CGRctZero];
topImage.image = [UIImage imageNamed:#"topim"];
[self.view addSubview:topImage];
// Add your UINavigationController here (or in Interface builder)
}
- (void) viewWillLayoutSubviews {
topImage.frame = CGRectMake(0, 0, 320, 20);
navController.view.frame = CGRectMake(0, 20, 320, self.view.bounds.size.height - 20);
}

Related

How to Set SubView Size Same as Navigation bar Size?

Here I have created Navigation bar with height 50 and width as view size.Now, I want to add a subview in the navigation bar with same navigation bar size.How to set the frame size for subview?
ViewController.m
-(void)ViewDidLoad
{
UINavigationBar *navbar = [[UINavigationBar alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 50)];
[self.view addSubview:navbar];
}
Firstly, your code won't respond to the orientation changes (portrait / landscape handling) nor support split screen. To fix it, instead of setting frame in viewDidLoad (where btw you do not call super!) write:
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
[self.navBar setFrame:CGRectMake(0, 0, self.view.frame.size.width, 50)];
}
Then as it is a different view, you should create a subclass of your view. The code will work in a way as #raghu wrote, but it won't be easily maintanable and will be of low quality. Separate of concerns!
Inside your UIView subclass you should implement init methods and layoutSubviews where you should set a proper frame.

iOS hidesBarsOnSwipe status bar background color

When I swipe and hide the navigation bar with the hidesBarsOnSwipe property the status bar has a clear background. How can I set the background of the status bar to the same color as the navigation bar? Here are a few pictures showing my problem, this is all contained in a UITableViewController.
Separate
Separate picture, looks like one big one.
I've come across the same issue, and was able to solve it. I'm fairly new to iOS dev, and I don't imagine this solution to be foolproof. I couldn't find any good answers elsewhere, so here's how I overcame it:
I converted from a UITableViewController over to UIViewController with a nested UITableView. Note, double check that the delegate to the child tableview is set to the UIViewController.
I Added a view with a height of 20px and a background colour that you want to set as the "background" to the status bar. Set the constraints on that view as follows:
On your table view, set the constrains to be basically full screen. One important note here, the top constraint is to "Top Layout Guide.Top" and not to "Top Layout Guide.Bottom". By default I believe this constraint ties to the bottom. Double clicking on the constraint allows you to adjust it to the top. Without this, any table header cells weren't positioned properly for me
Hope that helps.
Adding to George Huber's answer. I solved this issue programmatically by adding a 20pt height UIView as a subview of the navigationController's view property -- in viewDidLoad method.
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *statusBarBG = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), 20)];
statusBarBG.backgroundColor = [UIColor navBar];
[self.navigationController.view addSubview:statusBarBG];
// REST OF CODE
}
Per skg's answer, I add a relative height for status bar according to iOS version.
self.navigationController.hidesBarsOnSwipe = true;
// add a UIView as subView to navigationController
CGFloat statusBarHeight;
if (#available(iOS 13, *)) {
NSArray *windows = UIApplication.sharedApplication.windows;
UIWindow *keyWindow = nil;
for (UIWindow *window in windows) {
if (window.isKeyWindow) {
keyWindow = window;
break;
}
}
statusBarHeight = keyWindow.windowScene.statusBarManager.statusBarFrame.size.height;
NSLog(#"statusBarHeight: %f", statusBarHeight);
} else {
statusBarHeight = UIApplication.sharedApplication.statusBarFrame.size.height;
}
UIView *statusBarBG = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), statusBarHeight)];
statusBarBG.backgroundColor = [UIColor systemBackgroundColor];
[self.navigationController.view addSubview:statusBarBG];

How to design custom navigation bar

I have searched lots for how to design navigation like given in the image.
I have created category for UINavigationBar like given in the following solution
Custom nav bar styling - iOS
Able to increase the size of NavigationBar using below code.
CGFloat navBarHeight = 84.0f;
CGRect frame = CGRectMake(0.0f, 0.0f, 320.0f, navBarHeight);
[self.navigationController.navigationBar setFrame:frame];
But all content like (left button, right button, title) moves to bottom of bar.
When attach segment control to titleView like below
self.navigationItem.titleView = self.segmentedControl;
All views( left button, title, right button) as liner.
I want segment control bottom of the navigation bar as shown in the image.
#Shankar Shinde why are you adding segment controller as navigation title view you can add below the navigation bar using storyboard: check below screen shot
I think you need to hide the navigation bar using following code and create view like attached screenshot let me know it's help you or not ?
[self.navigationController.navigationBar setHidden:YES];
Please check it out sample:
https://github.com/boctor/idev-recipes/tree/master/WoodUINavigation
It may help you :)
You can use Prompt provided for navigationItem
First give prompt to your navigationItem
self.navigationItem.prompt = #"";
Create a segmentcontroll
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:itemArray];
segmentedControl.frame = CGRectMake(35, 200, 250, 50);
segmentedControl.segmentedControlStyle = UISegmentedControlStylePlain;
segmentedControl.selectedSegmentIndex = 1;
[self.navigationController.navigationBar addSubview:segmentedControl];

How to make Navigation Bar like Instagram

I need to implement something like this:
tableView must bounce, but not navigation bar.
I tried a bunch of different variants.
Something like this:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGRect imageViewFrame = self.imageView.frame;
CGRect tableViewFrame = self.tableView.frame;
//ImageView - is top view(instead of NavBar)
//defaultHeight - is default height of tableView
imageViewFrame.origin.y = MIN(0, MAX(-scrollView.contentOffset.y, -100));
tableViewFrame.origin.y = imageViewFrame.origin.y + 100;
tableViewFrame.size.height = defaultHeight - imageViewFrame.origin.y;
self.imageView.frame = imageViewFrame;
self.tableView.frame = tableViewFrame;
}
Get this:
it is not suitable because in Instagram size of tableView doesn't change(just look at scroll indicators, if size of tableView changed, they also changed)
Also I tried add View as subView into tableView, it works, but not exactly what I need is.
In Instagram navigation bar outside the tableView, so it is not suitable too.
In the facebook app search bar behaves exactly the same
Can anyone help me?
Thanks!
Have the same approach in the sample code but rather than increasing the tableview's height, you have it preloaded with the additional (not-visible height) and just move it upwards by decreasing the frame's y. The additional height will be off-screen. If the content height is not big enough to go off-screen then you don't need to have the off-screen height.
Add a header with height = 0 at start, and as you scroll down it increases the size, up to 100 (the empty header will be off screen now). That way the content will not get cut off as you scroll.
The instagram "navigation bar" isn't a navigation bar. It's a table section header. You'll notice that when you tap on a photo, the entire navigation bar slides away. That's because it's part of the table view controller and not a "real" navigation bar.
You can achieve this by using a UINavigationController but hiding the navigation bar (setNavigationBarHidden:YES). You just call pushViewController:animated: manually when you want to push.
Interestingly it looks like the other tabs of instagram just use a normal navigation bar and don't do anything fancy. I guess they really wanted those 44 points back on the main feed screen.
If you are targeting iOS 5+ than you can easily customize the navigation bar like this:
1- Add Your TableViewController inside a UINavigationController
2- Customize The Navigation Bar:
Set Background Image For Navigation Bar
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"bar_background"]
forBarMetrics:UIBarMetricsDefault];
Add Refresh Button on Right Side
UIImage *img = [UIImage imageNamed:#"refresh.png"];
UIButton *rButton = [UIButton buttonWithType:UIButtonTypeCustom];
[rButton setImage:img forState:UIControlStateNormal];
[rButton addTarget:vc action:#selector(didTapRefreshButton:) forControlEvents:UIControlEventTouchUpInside];
rButton.frame = CGRectMake(0.0f, 0.0f, img.size.width, img.size.height);
UIBarButtonItem *rButtonItem = [[UIBarButtonItem alloc] initWithCustomView:rButton];
self.navigationItem.rightBarButtonItem = rButtonItem;
[rButtonItem release];
Hope that Helps!
You can use the below mentioned method in your class in which you want to add effect on navigation bar as there in Instagram.
- (void)scrollViewDidScroll:(UIScrollView *)sender {
//Initializing the views and the new frame sizes.
UINavigationBar *navbar =self.navigationController.navigationBar;
UIView *tableView = self.view;
CGRect navBarFrame = self.navigationController.navigationBar.frame;
CGRect tableFrame = self.view.frame;
//changing the origin.y based on the current scroll view.
//Adding +20 for the Status Bar since the offset is tied into that.
if (isiOS7) {
navBarFrame.origin.y = MIN(0, MAX(-44, (sender.contentOffset.y * -1))) +20 ;
tableFrame.origin.y = navBarFrame.origin.y + navBarFrame.size.height;
}else{
navBarFrame.origin.y = MIN(0, (sender.contentOffset.y * -1)) +20;
tableFrame.origin.y = MIN(0,MAX(-44,(sender.contentOffset.y * -1))) ;
}
navbar.frame = navBarFrame;
tableView.frame = tableFrame;
}

How to also animate subview in navigation bar?

I have a subview in my navigation bar. I try to add it by this way:
UIView *customView =
[[UIView alloc] initWithFrame:
CGRectMake(0, 0, image.size.width + label.frame.size.width, 44)];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
[customView addSubview:imageView];
[customView addSubview:label];
[self.navigationController.navigationBar addSubview:customView];
However, when I try to push the navigation bar, the customView stays in the place, not animating following the sliding navigation bar. How can I achieve the animated subview? Is it even possible? Thanks!
you should not add subview in that way
you have tospecify your view location in the left , right or title view
self.navigationItem.titleView = YOURVIEW;
or choose another location left or right items in this way the the title view will added to the current view if you want to remove it just set it to nil in the place you want and reload it subviews again,
self.navigationItem.titleView = nil;
As you are using
[self.navigationController.navigationBar addSubview:customView];
that means the navigation bar you have create is in App delegate and is common for all the viewControllers in your project,that is why once you add a view on to it you see it on every view you have. Remove your sub-view in
-(void)viewWillDisappear:(BOOL)animated{
[Your subview remove fromSuperView];
[super viewWillDisappear:YES];
}
and add that subview in
-(void)viewWillAppear:(BOOL)animated{
[self.navigationController.navigationBar addSubview:Your subview];
[super viewWillAppear:YES];
}
this will add the subview in that particular view only and remove it as soon as that view is popped or pushed.The code given is not correct to the syntax please give a check on that.

Resources