This question already has answers here:
iOS 7 - Status bar overlaps the view
(14 answers)
Closed 8 years ago.
I am having a rather trivial example, where I compose a pretty simple layout:
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
self.window.rootViewController = self.someController;
...
Now the problem is, that the content of my viewcontroller is below the statusbar (20px).
Is the recommended way to manually resize my viewcontroller and move it 20px to the bottom, or is there any smarter way of handling this?
Note: I do not want to use e.g. UINavigationController.
[edit]
To clarify, some more code:
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.menuController = [[MenuController alloc] init];
CalendarViewController* center = [[[CalendarViewController alloc] init] autorelease];
IIViewDeckController* rootController = [[IIViewDeckController alloc] initWithCenterViewController:center leftViewController:self.menuController];
rootController.leftLedge = [[UIScreen mainScreen] bounds].size.width - 320.0;
rootController.delegate= self.menuController;
self.window.rootViewController = rootController;
[self.window makeKeyAndVisible];
}
As you can see, I'm using the IIViewDeckController (Link) as root controller. Currently it looks like this:
Use this code in viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
if([self respondsToSelector:#selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout=UIRectEdgeNone;
}
Please let me know if you are still facing the same problem.
The correct way to do this is to align all your views to the topLayoutGuide of the view controller. The layout guide will handle pushing your views down for the status bar, the in-call bar and if you move to a navigation controller later.
Related
I'm trying to use onboarding library start the app, I'm not using any navigation controller this is my didFinishLaunchingWithOptions function
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
_mobileOnboardVC = [[MobileOnboardViewController alloc]init];
_onboardVC =[_mobileOnboardVC loadOnboard];
_onboardVC.view.frame = [[UIScreen mainScreen] applicationFrame];
self.window.rootViewController = _onboardVC;
[self.window makeKeyAndVisible];
return YES;
And I'm getting this screen, can anyone point me out what's wrong with my code? Thank you
I'm not sure from your code what you are using as a navigation system, but that appears to be a navigation bar on the screen and you can remove that by doing the following:
in your viewdidload of the view controller you are presenting, just type this:'
[self.navigationController.navigationBar setHidden:TRUE];
You should also put this in your viewWillAppear in the same viewcontroller so that when the page is loaded from a "back button" press, this bar is removed as well.
So, this:
- (void)viewDidLoad {
[super viewDidLoad];
[[self navigationController] setNavigationBarHidden:TRUE];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[self navigationController] setNavigationBarHidden:TRUE];
}
It's the background picture I'm using causing this problem. I'm using a big picture for the content image, the gap should be part of my background image. To solve this, I need use a small image like an icon as page content, then it will work.
I have an empty application and there is no storyboard or xib involved. I want to have a hidden status bar and support only landscape orientation. Again, I wan't to make those changes only within code and don't touch the Info.plist.
Problem
I create a UIWindow with a controller that says the only supported orientation is landscape. In that case my UIWindow is created in the dimension of portrait mode and doesn't rotate. The expected result would be a screen that is completely cyan.
This is my delegate:
#import "AppDelegate.h"
#import "AppViewController.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = [UIColor cyanColor];
self.window.rootViewController = [[AppViewController alloc] init];
[self.window makeKeyAndVisible];
return YES;
}
#end
This is my controller:
#import "AppViewController.h"
#implementation AppViewController
- (BOOL)shouldAutorotate {
return YES;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeLeft;
}
- (BOOL)prefersStatusBarHidden {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
#end
What I've tried so far
If I set the rootViewController after calling makeKeyAndVisible everything seems to work at first.
self.window.backgroundColor = [UIColor cyanColor];
[self.window makeKeyAndVisible];
self.window.rootViewController = [[AppViewController alloc] init];
There are still some issues. First of all I don't like this since it seems to be very fragile. Second problem is that in a more complex application that sets a GLKViewController as the rootViewController I get the following result (expected would be no black area on the left):
It looks like the status bar is not hidden early enough. Several gesture recognizers are active and in the GLKViewController and clicking on the black area yields the following log message:
2014-09-25 13:20:42.170 StackOverflowExample[6971:107907] unexpected nil window in
_UIApplicationHandleEventFromQueueEvent, _windowServerHitTestWindow: UIClassicWindow: 0x7fa20b805e00; frame = (0 0; 375 667);
userInteractionEnabled = NO; gestureRecognizers = NSArray:
0x7fa20b80a620; layer = UIWindowLayer: 0x7fa20b806890
I also performed various other changes, like attaching an empty UIViewController and adding my view as a sub-view. In that case my view looks correct but the window is still using the wrong dimensions.
Everything rotates correct if I do not override the supportedInterfaceOrientations methods in my view controller. But that is of course not what I want.
When you run landscape app from portrait mode UIScreen has portrait bounds in iOS 8 (only if you haven't this app in app switch panel, as iOS 8 makes some cache). Even displaying window with makeKeyAndVisible doesn't change it's frame. But it changes [UIScreen mainScreen].bounds according to AppViewController avaliable orientation.
#import "AppDelegate.h"
#import "AppViewController.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Portrait bounds at this point
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = [UIColor cyanColor];
self.window.rootViewController = [[AppViewController alloc] init];
[self.window makeKeyAndVisible];
return YES;
}
#end
So let's change window's frame after [self.window makeKeyAndVisible]
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [UIWindow new];
self.window.backgroundColor = [UIColor cyanColor];
self.window.rootViewController = [[AppViewController alloc] init];
[self.window makeKeyAndVisible];
// Here it is
self.window.frame = [UIScreen mainScreen].bounds;
return YES;
}
I think that it is iOS 8 bug.
I had a similar problem, for a portrait-only app.
I fixed the problem by setting status bar orientation BEFORE instantiate the UIWindow
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Init my stuff
// ...
// Prepare window
[application setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO]; // prevent start orientation bug
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window makeKeyAndVisible];
return YES;
}
In your case, you should use UIInterfaceOrienationLandscapeLeft (or Right) in the setStatusBarOrientation:animated: method.
Hope it helps you.
Personally, none of the solution presented above worked. I finally set "hidden" to YES for the window in my main xib, as first suggested here: unexpected nil window in _UIApplicationHandleEventFromQueueEvent, _windowServerHitTestWindow
You can rotate UIWindow by adding single line only.
You can set the rootController for your UIWindow. e.g:
fileprivate(set) var bottonOverlayWindow = UIWindow()
self.bottonOverlayWindow.rootViewController = self;
// 'self' will the ViewController on which you had added UIWindow view. So whenever you ViewController change the orientation, your window view also change it's orientation.
Let me know if you face any issue.
The problem is solved when adding a Launch Screen, which you can only do by adding an extra property to the info.plist
had this problem myself, i'm not sure if you can add it through code though, i only managed to make it work with info.plist + Launch Screen xib file
<key>UILaunchStoryboardName</key>
<string>Launch Screen</string>
Actually i don't think you have to add a xib file, if just the key (with any value) is available in the plist it should work.
None of the solutions posted here or elsewhere worked for me.
However, I found that this issue apparently does not occur with Storyboards, so an alternative solution is to move away from xibs. (This fact sadly also makes it unlikely that Apple will take the problem seriously.)
I found some sample code.
It show the view by following code in AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (notification) {
NSLog(#"AppDelegate didFinishLaunchingWithOptions");
application.applicationIconBadgeNumber = 0;
}
AITPreviewViewController *previewViewController = [[AITPreviewViewController alloc] initWithNibName:#"AITPreviewViewController" bundle:nil];
navigationController = [[UINavigationController alloc]initWithRootViewController:previewViewController];
[self.window setRootViewController:navigationController] ;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
The following picture is in the AITPreviewViewController.xib.
But the View is not normal when it run on the iPhone , it show like the following picture.
The three imageView on the top has been obstructing by navigationItem
But when I turn to other View , and use the following code to turn back.
UIViewController *Previewer = [[AITPreviewViewController alloc] initWithNibName:#"AITPreviewViewController" bundle:nil] ;
Previewer.edgesForExtendedLayout = UIRectEdgeNone;
[self.navigationController pushViewController:Previewer animated:YES];
It show the normal View like the following picture.
The View only show not normal at first time...
What happened to this condition ?
Can it use Auto-layout to solve this problem ?
If you don't want to hide navigation bar then in your xib just make a little change
Just change the Top Bar property from none to as shown in image. It will auto place your image below the navigation bar
Try increasing the 'Y' value for those 3 images from your interface builder. Select each image and then go to Size Inspector. There you will see some values. Find the Y value and increase it. This will push the images down.
If you want to show only UI according to "AITPreviewViewController.xib"
Then you can hide your navigation bar.
I'm creating a simple application with uitableview. I want to create everything in code. I used following code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
FBVCalendarViewController *calendarViewController = [[FBVCalendarViewController alloc] init];
self.window.rootViewController = calendarViewController;
[self.window makeKeyAndVisible];
return YES;
}
...
- (void)loadView
{
UITableView *calendarItems = [[UITableView alloc] init];
self.view = calendarItems;
}
it works, but application fills the entire phone screen intersecting with standard phone title bar.
What is the right way to adjust view height?
Since UITableView inherits from UIScrollView, you should take care of the changes appeared with IOS 7.
A solution to your problem is:
if ([self respondsToSelector:#selector(setNeedsStatusBarAppearanceUpdate)]) {
[self setNeedsStatusBarAppearanceUpdate];
self.automaticallyAdjustsScrollViewInsets = NO;
}
(this will keep the table view below the status bar).
Hope that helps. But you should probably have a look at changes introduced with IOS 7.
So I solved my problem with the following code in loadView:
- (void)loadView
{
UITableView *calendarItems = [[UITableView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
UIView *rootView = [[UIView alloc] init];
[rootView addSubview:calendarItems];
self.view = rootView;
}
I used empty UIView as a parent for tableView and changed constructor to explicitly specify UITableView frame. I think that better approach would be to use autolayout (currently it just does not work as expected when I rotate device) and position table view to the full screen or implement device rotation callback and update frame there.
I'm trying to manually (programmatically) lay out views in a UITabBarViewController. I instantiate my UITabBarViewController like this:
MYAppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UITabBarController *tabBarController = [[UITabBarController alloc] initWithNibName:nil bundle:nil];
MYViewController1 *myViewController1 = [[MYViewController1 alloc] init];
myViewController1.title = #"My VC 1";
[tabBarController addChildViewController:myViewController1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.rootViewController = tabBarController;
return YES;
}
MYViewController1.m
- (void)viewDidLoad
{
[super viewDidLoad];
_myView = [[MYView alloc] initWithFrame:self.view.frame];
[self.view addSubview:_myView];
}
MYView.m
- (void)layoutSubviews
{
CGRect descriptionRect, buttonRect;
CGRectDivide(self.frame, &buttonRect, &descriptionRect, 50.f, CGRectMaxYEdge);
_descriptionTextView.frame = descriptionRect;
[self addSubview:_descriptionTextView];
_myButton.frame = buttonRect;
[self addSubview:_myButton];
}
The problem I'm having is that when I get to layoutSubviews, the superview's frame is the full size of the window, so the button is hidden by the tab bar. What am I doing wrong?
Without seeing more code, it appears that you may have some confusion about the use of a UITabBarController.
In the code you have posted above you are initializing a UITabBarController, then a UIViewController, and then you are calling 'addChildViewController:' on the tabBarController. (however, addChildViewController: is an instance method on UIViewController).
Is this in attempt to add the ViewController as a tab of the TabBarController? If so, then try the following code in place of addChildViewController: to see if it gives you the functionality that you are looking for:
tabBarController.viewControllers = #[myViewController1]; // Passing an array of viewControllers will set them as a tabs on the TabBar in the order they are added to the array.
If that doesn't help, then please comment on this answer with more details regarding the desired functionality of your code, and I'll update my answer to assist you as much as I can.
EDIT: Looks like I may have misunderstood your problem. Can you try the following code in play of your subview's initialization:
_myView = [[MYView alloc] initWithFrame:self.view.bounds]; // Try bounds instead of frame.