Auto Layout with navigation bar and view controller (iOS 7) - iphone

I'm currently transiting my application to iOS 7 (I want it to remain iOS 6 compatible). This question is not covered by the Apple NDA, it is a question about Auto Layout (it seems that iOS 7 forces Auto Layout (EDIT : was wrong, it is not forced)).
I have a navigation controller with a root view controller (obvious). With iOS 6, i was not using Auto Layout, so the root view controllers was below the navigation bar. With iOS 7, the frame origin does not include the navigation bar, so the top part of my content is hidden...
Have you an idea how to make the entire view above the navigation bar with Auto Layout ?
Thanks !

On iOS 7 you have the topLayoutGuide that specify the navigation bar. You can then specify that you want that the constraint of the tableview is on the topLayoutGuide and not the superview.
This will help you to know if it's iOS7 or not:
if ([self respondsToSelector:#selector(topLayoutGuide)])
So it can be something like that
NSString *verticalConstraint = #"V:|[v]|";
NSMutableDictionary *views = [NSMutableDictionary new];
views[#"v"] = self.tableview;
if ([self respondsToSelector:#selector(topLayoutGuide)]) {
views[#"topLayoutGuide"] = self.topLayoutGuide;
verticalConstraint = #"V:[topLayoutGuide][v]|";
}
[constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:verticalConstraint options:0 metrics:nil views:views]];
[self.view addConstraints:constraints];

Related

ios7 UINavigationBar stops extending under status bar after a while

First of all - this is NOT a question about navigation bar overlapping status bar (as many others).
UINavigationBar (of my navigation controller) is perfectly aligned as I want.
The problem is with my navigation bar custom background.
Background image (or navigation bar itself) stops expending under status bar randomly (after few seconds after my application starts or when I present / dismiss modal navigation controllers over it).
My custom image has proper dimensions for iOS (640x128px).
1. Initial look (desired - custom 640x128px background extends nicely under status bar):
2. After a while (flickers by itself):
What could cause such random flickering of UINavigationBar background image?
I use following code to configure my background:
// Load resources for iOS 7 or later
[[CustomNavigationBar appearance] setBackgroundImage:[self imageNamed:#"bg_top_ios7.png"] forBarMetrics:UIBarMetricsDefault];
[[CustomNavigationBar appearance] setBackgroundImage:[self imageNamed:#"bg_top_ios7.png"] forBarMetrics:UIBarMetricsDefaultPrompt];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
My status bar settings in the Info.plist file:
I have also following settings in my UIViewController subclass init method (not sure if it matters):
-(id)init{
//DLog(#"BaseViewController init...");
if (self = [super init]) {
popToRoot = modal = NO;
rootIndex = 0;
indexInBottomNavigation = 0;
[Crashlytics setObjectValue:#"init" forKey:NSStringFromClass([self class])];
// iOS 7 adoptions:
if ([self respondsToSelector:#selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;
if ([self respondsToSelector:#selector(extendedLayoutIncludesOpaqueBars)])
self.extendedLayoutIncludesOpaqueBars = YES;
if ([self respondsToSelector:#selector(automaticallyAdjustsScrollViewInsets)])
self.automaticallyAdjustsScrollViewInsets = NO;
}
return self;
}
My view controllers are embedded in UINavigationController (which takes care of UINavigatioBbar positioning).
I am also using ECSlidingViewController (reveal container) as a container for my navigation controllers but I am not sure if it matters.
It turned out I was changing clipsToBounds = YES of navigation controller's navigation bar (somewhere in the app):
navigationController.navigationBar.clipsToBounds = YES;
In order for UINavigationBar to extend its background under status bar
its clipsToBounds must be set to NO (which is the default).
Make sure you do not mock around with it.
Solution simple as:
navigationController.navigationBar.clipsToBounds = NO;

NavigationBar hides TableView in TabBarViewController

I have a ViewController that Pushes a TabBarViewController. Inside that TabBar View Controller I have 4 tabs. Two of these tab bars are UITableViewControllers and the other two are ViewControllers. The first tab is a table view controller and is working fine, ie not being hidden by the navigation bar. The third tab, which is another TableViewController, is being partially covered by the navigation bar. The first section and first cell is being hidden underneath the navigation bar. Has anyone had this problem in the past or does anyone know a solution to this? I've tried a couple of things like resizing the frame size manually
self.tableView.frame = CGRectMake(10,10,self.view.bounds.size.width -20, self.view.bounds.size.height-20);
That did't seem to work. I tried AutoLayout as well and didn't work. I don't know what else to do. Anyone have any suggestions or ideas of how to tackle this.
Edit: I've tried the edgesForExtendedLayout but it is making my navigationbar a darker color. It animates the color change in the navigationbar, sort of like a loading bar.
Note: This is only happening in ios7. I just simulated it in iOS 6.1 and the navigationbar does not cover the table view controller at all, which is weird to me. Any one have any suggestions?
Edit #2: Noticing that this is an iOS 7 > problem i did the following but now the navigation bar has changed color to a darker color.
if([[[[UIDevice currentDevice] systemVersion] componentsSeparatedByString:#"."][0] intValue] >= 7)
{
if ([self respondsToSelector:#selector(edgesForExtendedLayout)])
{
self.edgesForExtendedLayout = UIRectEdgeNone;
self.extendedLayoutIncludesOpaqueBars = YES;
self.automaticallyAdjustsScrollViewInsets = NO;
}
}
In the viewDidLoad method of UITableViewController (assuming it's loaded with a call to the tabBarController) that is associated with the tabs use
if ([self respondsToSelector:#selector(edgesForExtendedLayout)]) {
self.edgesForExtendedLayout = UIRectEdgeNone;
self.tableView.contentInset = UIEdgeInsetsMake(0., 0., CGRectGetHeight(self.tabBarController.tabBar.frame), 0);
}
I fixed that with:
if ([self respondsToSelector:#selector(edgesForExtendedLayout)]) {
viewcontroller.edgesForExtendedLayout = UIRectEdgeNone;
viewcontroller.extendedLayoutIncludesOpaqueBars = NO;
viewcontroller.automaticallyAdjustsScrollViewInsets = NO;
}

iOS 7 status bar overlap the text in view

iOS 7 status bar overlap the view. The text shows in the header of the screen. I want to show the screen with out the text in header called "Carrier, 4:49, and Battery"
How to handle this in iOS 6 and iOS 7 ?
You could hide it, I think that would look better in your case.
In your app plist add this
View controller-based status bar appearance, and set to NO
I think that it can help you:
if ([self respondsToSelector:#selector(edgesForExtendedLayout)]) {
self.edgesForExtendedLayout = UIRectEdgeNone;
}
Its not a iOS 7 problem. Because status bar is transparent in iOS7. So you need to handle it manually.So please use right image here.
Unfortunately you are not the only one with this problem,
while on iOS before 7 the {0, 0} point was just below the status bar it is now at the top of the screen my advice is to add +20.0f to every y coordinate if in iOS 7
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
// normal comportment
} else {
// add 20.0f offset
// you might also want to add a UIImageView subview to go behind the status bar (20pt of height, full width)
}
you might do it in view didLoad, for my part I calculate my elements position in static variables initialized in the +(void)initialize class method of my view controllers
if in -(void)viewDidLoad something like
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
// normal comportment
} else {
for (UIView *v in self.view.subviews) {
CGRect oldFrame = v.frame;
v.frame = CGRectMake(oldFrame.origin.x, oldFrame.origin.y + 20.0f, oldFrame.size.width, oldFrame.size.height);
}
// you might also want to add a UIImageView subview to go behind the status bar (20pt of height, full width)
}
This may help you How to fix iOS 7 Status bar overlapping issue and status bar style
which worked for me.

Is it possible to dim the entire iPhone screen while keeping one view on top?

I have a UITabbar-based iphone app with a NavigationController bar on the top. I also have a logout view that I present on top, while dimming the background. You can see here: http://d.pr/i/XH6x
However, the dimmed background does not cover the UINavigationBar on top nor the UITabbar on the bottom. How can I dim the entire screen, while keeping the LogoutView on top?
Right now, I'm doing the dimmed view with this code:
UIView *dimView = [[UIView alloc] initWithFrame:self.collectionView.frame];
dimView.tag = kDimView;
dimView.backgroundColor = [UIColor blackColor];
dimView.alpha = 0.7;
[self.view addSubview:dimView];
Thank you!
EDIT: I should mention that this is a UITabBarController based application, with UInavigationControllers for each of the 3 tabs.
try this.
UIWindow* mainWindow = [[UIApplication sharedApplication] keyWindow];
dimView.frame = CGRectMake(00, 00,mainWindow.frame.size.width , mainWindow.frame.size.height);
Hope this will help you.
You have to dim the view, where your tabbar and navigation bar lies.
For example, there is one UIViewController named RootViewController, which contains your UITabbarController and UINavigationController.
So try to set alpha value for that view, and then do add subview normally, as you are doing.

Navigation Bar partially hidden only in iOS5

I have a Tab Bar Controller with Nav Controller. In this Nav Controller have a Navigation Bar.
The implementation it's very simple, there are not custom code. I do all with graphical interface in Xcode.
If I open the application in iOS4 it's perfect.
But If I open in iOS5 or iOS 5.0.1 ... It's partially hidden with status bar.
How I can fix it?
EDIT: This is my implementation in MainWindow.xib (sorry I need remove some names)
I Had the same problem with an old project made by other devs who used the xib.
My solution is that you have to write some code:d if you did the drag and drop programing approach.
So:
In viewWillAppear move all your ui elements with 20 pixels down.
I added tags in xib for each element and with a static int I keep tract of changes to be done only once.
static int oneTine = 0;
if(!oneTine){
for(int index = 1001; index<=1005; index++){
UIView *currentView = [self.view viewWithTag:index];
CGRect viewFrame = currentView.frame;
viewFrame.origin.y -=20;
currentView.frame = viewFrame;
}
oneTine = 1;
}