How to also animate subview in navigation bar? - ios

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.

Related

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 Customize navigation bar in XCode5 iOS7 in AppDelegate file?

I am trying to customise the navigation bar of my iPhone app. I want to add an image in the left side of the navigation bar title.
I tried the following code from the didFinishLaunchingWithOptions of the AppDelegate.m file:
UIView *myView = [[UIView alloc]initWithFrame:CGRectMake(170, 10, 20, 20)];
UIImageView *image = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"logo.png"]];
[myView addSubview:image];
[self.navigationController.navigationBar addSubview:myView];
self.navigationController.navigationItem.titleView=myView;
but it doesn't work. When I try it from the viewDidLoad of one of my ViewControllers it works. But i want to inherit this behaviour in all my ViewControllers
UINavigationItem has a property, titleView. You need to set that to your custom view, and then that view will replace the standard title (so you need to have your image and a label for the title in your custom view).
self.navigationItem.titleView = myView;

Adding a new view on top of an existing view

I want to add a view called anotherView on top of self.view. But I don't want anotherView to be a subview. Is this possible?
I want anotherView to be at the top of the page and push the contents of self.view down accordingly (without having to change the y or height values.
I have the following and it doesn't work:
UIView *anotherView = [[UIView alloc] initWithFrame: CGRectMake(0, 0, self.view.frame.size.width, 80)];
anotherView.backgroundColor = [UIColor yellowColor];
[self.view insertSubview:anotherView aboveSubview:self.view];
The box is simply on top of the existing view.
Any visible view is subview of some other view or window.
But you can add anotherView to
self.view.superview
or even
self.view.window
or create new UIWindow object and add your subview to this window
Have you tried to present anotherView modally? That way you can make it to appear on top of everything being a completly new view controller. Ex:
[self presentModalViewController:anotherView animated:YES];
assuming of course anotherView is a subclass of UIViewController and has its own View property. Because if anotherView is just subclass of UIView then you can't present it without being a subview of the current View Controller.
EDIT:
Oh yes, you can just pass a nil to the completion block:
[self presentViewController:anotherView animated:YES completion:nil];

UIImageView over Navigation bar and main screen

I have an UImage that I need half on the navigation bar and half on the main screen. I have added a Navigation Controller on my project so now I have a nav bar on all screens. I need a square image to go half on the navigation controller and half on the main screen.
In XCODE I have successfully put an UImageView over the nav bar and the main screen but when i put an image on it i only appears in the part thats over the main screen and not over the navigation bar. I don't want to split the image so I can use Navigationbar.image control - is there another way ?
Instead of adding it to viewController, add it to window.
UIView *view =[[UIView alloc] initWithFrame:CGRectMake(40, 30,240,60)];
view.backgroundColor =[UIColor greenColor];
[[[UIApplication sharedApplication] delegate].window addSubview:view];
As you might have noticed the UINavigationBar appears on top of everything you have within your UIViewController's view.
One way of overcoming this is by adding your UIImageView to the keyWindow like so:
UIImageView * imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
imageView.image = [UIImage imageNamed:#"myImage"];
[[UIApplication sharedApplication].keyWindow addSubview:imageView];

UITableView: Painting-Behavior of Header- and Footer-View

Why does the header and footer of a tableview always stays on top of the view hierarchy, but not the cells of the table?
Here is what I got:
A table view with custom cells, a footer and a header
A Navigationbar with a menu-Button on the right
When the user taps the menu-button, a semi-transparent menu (UIView) fades in from the top, but not over the navigationbar, only over the view of my tableviewcontroller
When the user tabs a menu-button, the menu slides back to (0,-menuHeight)
But when the menu is over the header, this menu-region is behind my header
I anchored the menu on the view of my tableviewcontroller, beacause I want the navigationbar allways be visible. the solution to anchor it on the navigationbar solves the problem with the header-view, but covers the navigationbar.
Has anyone an idea how to solve this problem? Why are the cells painted correctly?
You should probably not interfere directly with the internal view hierarchy of UITableView. Apple is free to order a table view's subviews as they see fit (and change it in future releases).
Instead, place the table view and your menu view into a common container view and make the latter the main view of your view controller. That way, you can be certain that your menu view will always be above the table view.
I changed my design, but now I do not get touch-events in my table.
But when I add this method - I see, that I'm touching the tableviewcontroller...
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(#"ShieldingViewController received touch");
[self.buttonMenu shieldingViewTouched];
}
Here is what I changed:
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect viewFrame = self.view.frame;
viewFrame.origin.y = 0;
UIView *rootView = [[UIView alloc] initWithFrame:viewFrame];
rootView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
// Setup the table view
UITableView *newTableView = [[UITableView alloc] initWithFrame:viewFrame style:self.tableView.style];
newTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
newTableView.backgroundColor = [UIColor darkGrayColor];
UIView *menuLayerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)];
self.tableView = newTableView;
[rootView addSubview:self.tableView];
[rootView addSubview: menuLayerView];
self.view = rootView;
[[CustomNavigationController instance] setCurrentViewForMenu: menuLayerView];
[[CustomNavigationController instance] showMenuInNavigationBarForController:self];
[newTableView release];
[menuLayerView release];
[rootView release];
}

Resources