I am creating navigation bar programmatically in my UIViewController in viewWillAppear. After I updated my iOS to iOS 11, the height remains constant and is not changing now. I checked all answers related to it on Stack but those answers are for UIView but not for UIViewController.
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
// Do any additional setup after loading the view.
UINavigationBar *navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0,0, self.view.frame.size.width, 50)];
navBar.barTintColor = [UIColor colorWithRed:160.0/225 green:72.0/225 blue:178.0/225 alpha:1.0];
[self.view addSubview:navBar];
}
Thanks for help!
Related
We have a problem where the user is using our app on the iPhone and receives a call while on a view that has been presented by the rootviewcontroller and is covering the navigation controller and it's nav bar. The status bar for the call shows and pushes the current view down but when that view is removed from the superview, the status bar covers half of the navigation bar.
We have tried using a UIApplicationWillChangeStatusBarFrameNotification in the app delegate and then adjusting the size of the navigation controller and the navigation bar to no effect. We have also tried resetting the frame of the navigation controller and nav bar in the viewWillAppear function of the page that presents the view.
Can anyone tell us where we are going wrong?
In App Delegate we tried this
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self setupAppStyles];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor ugBlue];
UINavigationController *navController = [[UINavigationController alloc] init];
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
[self setUpNotifications];
return YES; }
-(void) setUpNotifications {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(statusFrameChanged:)
name:UIApplicationWillChangeStatusBarFrameNotification
object:nil];}
- (void)statusFrameChanged:(NSNotification*)note {
CGRect statusBarFrame = [note.userInfo[UIApplicationStatusBarFrameUserInfoKey] CGRectValue];
self.statusHeight = statusBarFrame.size.height;
UIScreen *screen = [UIScreen mainScreen];
CGRect viewRect = screen.bounds;
viewRect.size.height -= self.statusHeight;
viewRect.origin.y += self.statusHeight;
[[UINavigationBar appearance] setFrame:viewRect];
NSLog(#"The status frame has changed");
//[self.navController.view setFrame:viewRect];
self.navController.view.frame.size.height);}
We have also tried something similar in the views viewWillAppear functions also with no positive results. Any thoughts?
We were able to solve this problem. In the viewDidAppear of the view that called presentViewController we put
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat navBarHeight = self.navigationController.navigationBar.frame.size.height;
CGRect frame = CGRectMake(0.0f, statusSize, screenRect.size.width, navBarHeight);
[self.navigationController.navigationBar setFrame:frame];
When the status bar is shown
I have an iPad app (XCode 5, iOS 7, Storyboards and ARC). I have a UIPopover created in a UIViewController, and when I tap a button it correctly displays the popover.
Now, I want to draw a grid in that popover; I know I have to add code to drawRect do do the drawing, and do a setNeedsDisplay to get the drawing done. However, it's not working!
My question is why is drawRect not being called when from [popoverView setNeedsDisplay]; ? Both methods are in the same UIViewController class.
Here is the code that is supposed to call the drawRect
// create popover
UIViewController* popoverContent = [[UIViewController alloc] init];
UIView *popoverView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 650, 416)];
popoverView.backgroundColor = [UIColor whiteColor];
popoverContent.preferredContentSize = CGSizeMake(650.0, 416.0);
// draw the lines, etc on the popoverContent
[popoverView setNeedsDisplay];
// create the popover controller and attach the popover content to it
popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
popoverController.delegate = (id)self;
[popoverController setPopoverContentSize:CGSizeMake(650, 416) animated:NO];
[popoverController presentPopoverFromRect:CGRectMake(650, 416, 10, 50) inView: obViewOpenAppts
permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
I have a breakpoint in drawRect so I know it's not being called.
What am I doing wrong?
drawRect: is a UIView method, not a UIViewController method. If you want to override it you have to subclass UIView, and then create it like this:
MyUIViewSubclass *popoverView = [[MyUIViewSubclass alloc] initWithFrame:CGRectMake(0, 0, 650, 416)];
So I'm creating a mac OSX app and right now I have a main view controller set up to be the size of the window and a NSView subview on top of the view controller with the same frame size. However, this is the result I am getting: (I colored the NSView subview pinkish)
What I want is for the whole window to be taken up by the NSView subview (so the whole window should be pink). Here is my code thus far:
In AppDelegate.m:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
self.mainViewController = [[NSViewController alloc]
initWithNibName:Nil bundle:Nil];
self.mainViewController.view.frame = ((NSView *)self.window.contentView).bounds;
[self.window.contentView addSubview:self.mainViewController.view];
}
And then in my view controller:
-(void)loadView
{
[super loadView];
NSView *myView = [[NSView alloc] initWithFrame:self.view.frame];
CALayer *viewLayer = [CALayer layer];
[viewLayer setBackgroundColor:CGColorCreateGenericRGB(100.0, 0.0, 0.0, 0.4)];
[myView setWantsLayer:YES];
[myView setLayer:viewLayer];
[self.view addSubview:myView];
}
What am I doing wrong?
Instead of adding a subview to your view controller in your loadView: method, you should set the view of view controller here as:
-(void)loadView
{
.
.
.
// [self.view addSubview:myView]; //update this to
[self setView: myView];
}
This is my code. I can see the small dialog box appeared then the dialog take over the whole screen. What is wrong?
ChangeProfileImage *changeProfileImage =[[ChangeProfileImage alloc] init];
changeProfileImage.modalPresentationStyle = UIModalPresentationFormSheet;
changeProfileImage.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:changeProfileImage animated:YES];
changeProfileImage.view.superview.frame = CGRectMake(0, 0, 200, 200);//it's important to do this after
changeProfileImage.view.superview.center = self.view.center
I was all ready to tell you everything that's wrong with this code, but then I set up a simple iPad single view application and tried the following code:
- (IBAction)FlipPressed:(id)sender {
UIViewController *vc = [[UIViewController alloc] init];
UIView *view = [vc view];
[view setBackgroundColor:[UIColor redColor]];
[vc setModalPresentationStyle:UIModalPresentationFormSheet];
[vc setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[self presentModalViewController:vc animated:YES];
[[[vc view] superview] setFrame:CGRectMake(0, 0, 200, 200)];
[[[vc view] superview] setCenter:[[self view] center]];
}
When I try this, I get a red box, 200x200, with rounded corners, that flips into view centered on screen.
As far as I can tell, I've replicated your code pretty much exactly, and I think I got the result you want, right?
EDIT/UPDATE
Further testing appears to indicate that this code will only work well when the iPad is in the portrait orientation. Otherwise, my view is appear to flip "vertically" (with respect to how the iPad is oriented) and the view isn't centered.
I just switched over to iOS 5 and everything appears to be working in my application aside from the custom navigation bar. I looked around and followed everybody's suggestion of calling the new methods setBackgroundImage: forBarMetrics: however it doesn't appear to work. This is the code I've tried to place both within the app delegate and within the viewDidLoad method of some of the view controllers:
UINavigationBar *nb = [[UINavigationBar alloc]init];
if( [nb respondsToSelector:#selector(setBackgroundImage:forBarMetrics:)] )
{
UIImage *image = [UIImage imageNamed:#"navBarBackground.png"];
[nb setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
}
[nb release];
Unfortunately this doesn't work. If anybody has any suggestions at all, I'm all ears!
To apply image to all your navigation bars, use the appearance proxy:
[[UINavigationBar appearance] setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
For an individual bar:
// Assuming "self" is a view controller pushed on to a UINavigationController stack
[self.navigationController.navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
In your example, the background image won't change because nb isn't hooked up to anything.
Answer by rob is correct but if application runs on iOS 4.3 or lower app will crash. So you can implement this like
if([[UINavigationBar class] respondsToSelector:#selector(appearance)]) //iOS >=5.0
{
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"navigationBar.png"] forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:#"navBar-Landscape.png"] forBarMetrics:UIBarMetricsLandscapePhone];
}
This will set image for both mode Landscape and Portrait
You need to get the navigation bar from a navigation controller. Right now you are just creating one and then it deallocs when you release it. You need to get the navigation controller for your view controller.
UINavigationController * navigationController = [self navigationController];
UINavigationBar * nb = [navigationController navigationBar];
Note that if you want to apply the same to a toolbar, it is slightly different. Here's an example, building on Rob's answer:
[[UIToolbar appearance] setBackgroundImage:[UIImage imageNamed:#"NavBarDarkWoodGrain.png"] forToolbarPosition:UIToolbarPositionBottom barMetrics:UIBarMetricsDefault];
You didn't do something like use a UINavigationBar subclass? If you do this and override drawRect: on iOS5 and above, things will break.
See my answer here for a way to support both OS versions.
This worked for me.
UIView *parentViewLeft = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
parentViewLeft.backgroundColor = [UIColor clearColor];
if ([self.navigationController.navigationBar respondsToSelector:#selector(setBackgroundImage:forBarMetrics:)]) {
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"navbar.png"]
forBarMetrics:UIBarMetricsDefault];
} else {
UIImageView* imgBG = [[UIImageView alloc]init];
imgBG.image = [UIImage imageNamed:#"navbar.png"];
imgBG.frame = CGRectMake(-10,0, 330, 44);
[parentViewLeft addSubview:imgBG];
}
UIBarButtonItem *customBarButtomLeft = [[UIBarButtonItem alloc] initWithCustomView:parentViewLeft];
self.navigationItem.leftBarButtonItem = customBarButtomLeft;