11

I have an app with a support landscape and portrait mode. And I need the same behavior status bar like on iOS 6. What is the simplest way to do this?

I've tried the solutions in Stack Overflow question iOS 7 status bar back to iOS 6 style?, but it doesn't work. My subview depend on the view size, and my view doesn't stretch correctly. I don't want to update my XIB files; I simply want to add something that helps me. I don't know what it may be (hack or prayers).

Community
  • 1
  • 1
Gralex
  • 4,285
  • 7
  • 26
  • 47
  • Do you have to compile against the iOS 7 SDK? If you don't need anything from iOS 7 then you should simply be able to compile against the SDK 6. At least for the time beenig. And Apps compiled with SDK6 with appropriate OS target should still have all the look and feel of pre-7 iOSes. – Hermann Klecker Sep 20 '13 at 13:05
  • I had similar problem. I downgraded XCode to version 4.6.3 and now it is fine (on any device with iOS 5-7). Changing SDK didn't fix problem, so XCode 5.0 has some annoying issues. – Marek R Sep 20 '13 at 13:06
  • 3
    Just don't understand why this question is closed. Obviously status bar style is important knowledge in iOS programming and this question could help lots of iOS programmers. Adopt iOS7 is not just changing a png. – Jay Zhao Sep 22 '13 at 01:31
  • working in case there is no navigation bar and creating a problem when navigation bar is there – Alok Singh Oct 04 '13 at 09:55
  • I suggest you need to set navigationController.navigationBar.translucent = NO; What problem you have? – Gralex Oct 04 '13 at 10:40
  • 2
    Oh god don't do that. Swizzling a method that other parts of your code will use, PLUS Apple's frameworks is the recipe for disaster.... – Javier Soto Oct 05 '13 at 20:16
  • I agree with you. It's dangerously to use this method. – Gralex Oct 07 '13 at 07:47
  • @Sk0prion Can you Please add the solution as answer?. – sathiamoorthy Nov 11 '13 at 06:35
  • Added solution as answer. Add one more solution) – Gralex Nov 11 '13 at 09:21

5 Answers5

3

You can try writing this in your ViewWillappear or DidAppear. Here we are shifting the view frame 20 pixels down.

CGRect frame = self.view.frame;
frame.origin.y = 20;

if (self.view.frame.size.height == 1024 || 
    self.view.frame.size.height == 768)
{
    frame.size.height -= 20;
}

self.view.frame = frame;

This will work, but however this is not a very good idea. You can also change the text colour of the status bar to light or dark depending on your app background by calling the following method if it helps.

-(UIStatusBarStyle)preferredStatusBarStyle
{
     return UIStatusBarStyleLightContent; // For light status bar

     return UIStatusBarStyleDefault // For Dark status bar
}
biddulph.r
  • 5,226
  • 3
  • 32
  • 47
Bhumit Mehta
  • 16,278
  • 11
  • 50
  • 64
  • I want put some code only 1 place, not everywere in app. Swizzling method on UIViewController bad solution: because I can [viewController1.view addSubview:viewController2.view] – Gralex Sep 20 '13 at 13:20
  • Try putting above code in your DidAppear method of viewController1 . As there are very few other ways if you want your app to look like iOS 6 . One of other option is to move all your subviews 20 px down but thats a lot of work – Bhumit Mehta Sep 20 '13 at 13:34
  • Thanks, if I don't find any simple solution, I will use yours solution. I don't want this, cause I have a lot of apps with many views. – Gralex Sep 20 '13 at 13:41
2

If you are on Xcode 5 and you are installing in iOS 7 then sorry, this will not happen (as far as I know).

If you want to see the status bar on iOS 7 like iOS 6 than open your project in Xcode 4.x.x and install in iOS 7. One problem with this approach I found is that sometimes Xcode 4.x.x doesn't recognise an iOS 7 device.

But if your Xcode 4.x.x can show your iOS 7 device then it will work.

The .api generated from Xcode 4.x.x will work in both iOS 6 and iOS 7, but you will not get extra space (of the status bar) on iOS 7 and the new look of keyboard, picker, switch, etc. But yes, you will get the new UIAlertView (I don't know why this is new and the other controls are old.)

I hope we will soon get a better solution in Xcode 5 for this.

UPDATE:

I found the way to run the app from Xcode 5 as Xcode 4. This is just matter of the base SDK. If you want to built as Xcode 4 (iOS 6 SDK) from Xcode 5 then do the following.

  1. Close Xcode 4 and 5.

  2. In Xcode 4 Go to

    /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs

  3. Here you will find iPhoneOS6.1.sdk. Copy this folder. And now go in Xcode 5 on the same path. In Xcode 5, you will find iPhoneOS7.0.sdk. Paste iPhoneOS6.1.sdk with it.

  4. Now close the Finder and launch Xcode 5. Go to project target setting -> Build Setting and find Base SDK. Select iOS 6.1 as Base SDK. This will also work for 6.0. You just need to find iPhoneOS6.0.sdk.

  5. Now you will see the device name twice in the run dropdown box. One for SDK 7.0 and one for SDK 6.1. So now you can run both ways with iOS 6 SDK and iOS 7 SDK.

I hope this will help someone.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
CRDave
  • 9,279
  • 5
  • 41
  • 59
  • I want upload my app on appstore. As I know, I have not chance to do this with xCode 4.6.x – Gralex Sep 20 '13 at 13:13
  • I have tried many solution online but nothing work for me. You can upload from Xcode 4.6.x I have upload two app from xcode 4.6.x and working fine. What extra you need is iOS 7 size icon. – CRDave Sep 20 '13 at 13:20
  • I ma eager to know that. – CRDave Sep 21 '13 at 07:55
  • I found this solution http://stackoverflow.com/questions/18294872/ios-7-status-bar-back-to-ios-6-style/18966372#18966372 – İbrahim Özbölük Sep 25 '13 at 17:17
  • This is incorrect. You can view as iOS 6 in Xcode 5. Choose it from Storyboard Settings in Interface Builder. Never use an old version of Xcode. – Raptor Jun 13 '14 at 02:46
  • @Raptor Yes you can see that in interface builder and that I know very well. But if you run in device which is iOS 7 you will not get that status bar there because Xcode use iOS SDK 7 to build app even is you select iOS 6 view in storyboard. – CRDave Jun 13 '14 at 05:01
0

I recently had to solve a similar problem, and I approached it in a slightly different way...

The approach was to use an extra view controller that acted as a container view controller for what was originally my rootViewController. First, i set up a container like this:

_containerView = [[UIView alloc] initWithFrame:[self containerFrame]];
_containerView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
_containerView.clipsToBounds = YES;

[self.view addSubview:_containerView];
[self.view setBackgroundColor:[UIColor blackColor]];

[UIApplication.sharedApplication setStatusBarStyle:UIStatusBarStyleLightContent animated:NO];

where the containerFrame was defined like this:

- (CGRect)containerFrame
{
    if ([MyUtilityClass isSevenOrHigher])
    {
        CGFloat statusBarHeight = [MyUtility statusBarHeight]; //20.0f
        return CGRectMake(0, statusBarHeight, self.view.bounds.size.width, self.view.bounds.size.height - statusBarHeight);
    }

    return self.view.bounds;
}

Finally, I added what was originally my rootViewController as a childViewController of the new one:

//Add the ChildViewController
self.childController.view.frame = self.containerView.bounds;
self.childController.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[self addChildViewController:self.childController];
[self.containerView addSubview:self.childController.view];
[self.childController didMoveToParentViewController:self];

Things to note: - Modal view controllers will still be presented in the iOS7 style, so I still have to account for that somehow.

Hope this helps someone!

Sean Danzeiser
  • 9,141
  • 12
  • 52
  • 90
0

This Guide helps me.

http://www.doubleencore.com/2013/09/developers-guide-to-the-ios-7-status-bar/

The most robust way to handle the 20 point size difference is Auto Layout.

If you aren’t using Auto Layout, Interface Builder provides you with tools to handle the screen size difference between iOS 7 and the older versions. When Auto Layout is turned off, you will notice an area in the sizing tab of the utility area (right pane) of Interface Builder that allows you to set iOS 6/7 Deltas.

-1

1) It's a hack, but it works!

Use it if you doesn't use UIAlertView or KGStatusBar!!!

#import <objc/runtime.h>

@interface UIScreen (I_love_ios_7)
- (CGRect)bounds2;
- (CGRect)boundsForOrientation:(UIInterfaceOrientation)orientation;
@end

@implementation UIScreen (I_love_ios_7)
- (CGRect)bounds2
{
    return [self boundsForOrientation:[[UIApplication sharedApplication] statusBarOrientation]];
}

- (CGRect)boundsForOrientation:(UIInterfaceOrientation)orientation
{
    CGRect resultFrame = [self bounds2];
    if(UIInterfaceOrientationIsLandscape(orientation))
        resultFrame.size.width -= 20;
    else
        resultFrame.size.height -= 20;
    return resultFrame;
}
@end

void Swizzle(Class c, SEL orig, SEL new)
{
    Method origMethod = class_getInstanceMethod(c, orig);
    Method newMethod = class_getInstanceMethod(c, new);
    if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))
        class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
    else
        method_exchangeImplementations(origMethod, newMethod);
}


@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
        Swizzle([UIScreen class], @selector(bounds2), @selector(bounds));
        [application setStatusBarStyle:UIStatusBarStyleLightContent];
        self.window.clipsToBounds =YES;

        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(applicationDidChangeStatusBarOrientation:)
                                                     name:UIApplicationWillChangeStatusBarOrientationNotification
                                                   object:nil];
        NSDictionary* userInfo = @{UIApplicationStatusBarOrientationUserInfoKey : @([[UIApplication sharedApplication] statusBarOrientation])};
        [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationWillChangeStatusBarOrientationNotification
                                                            object:nil
                                                          userInfo:userInfo];
    }

    return YES;
}

- (void)applicationDidChangeStatusBarOrientation:(NSNotification *)notification
{
    UIInterfaceOrientation orientation = [[notification.userInfo objectForKey: UIApplicationStatusBarOrientationUserInfoKey] intValue];
    CGSize size = [[UIScreen mainScreen] boundsForOrientation:orientation].size;
    int w = size.width;
    int h = size.height;
    float statusHeight = 20.0;
    switch(orientation){
        case UIInterfaceOrientationPortrait:
            self.window.frame =  CGRectMake(0,statusHeight,w,h);
            break;
        case UIInterfaceOrientationPortraitUpsideDown:
            self.window.frame =  CGRectMake(0,0,w,h);
            break;
        case UIInterfaceOrientationLandscapeLeft:
            self.window.frame =  CGRectMake(statusHeight,0,w,h);
            break;
        case UIInterfaceOrientationLandscapeRight:
            self.window.frame =  CGRectMake(0,0,w,h);
            break;
    }
}
@end

2) Create category, and always use contentView instead of view

@interface UIViewController(iOS7_Fix)
@property (nonatomic, readonly) UIView* contentView;
- (void)updateViewIfIOS_7;
@end

@implementation UIViewController(iOS7_Fix)
static char defaultHashKey;
- (UIView *)contentView
{
    return objc_getAssociatedObject(self, &defaultHashKey)?: self.view;
}

- (void)setContentView:(UIView *)val
{
    objc_setAssociatedObject(self, &defaultHashKey, val, OBJC_ASSOCIATION_RETAIN_NONATOMIC) ;
}

- (void)updateViewIfIOS_7
{
    if([[[UIDevice currentDevice] systemVersion] floatValue] < 7 || objc_getAssociatedObject(self, &defaultHashKey))
        return;

    UIView* exchangeView = [[UIView alloc] initWithFrame:self.view.bounds];
    exchangeView.autoresizingMask = self.view.autoresizingMask;
    exchangeView.backgroundColor = [UIColor blackColor];

    UIView* view = self.view;
    if(self.view.superview){
        [view.superview addSubview:exchangeView];
        [view removeFromSuperview];
    }
    [exchangeView addSubview:view];
    self.view = exchangeView;

    CGRect frame = self.view.bounds;
    frame.origin.y += 20.0;
    frame.size.height -= 20.0;
    view.frame = frame;
    view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

    [self setContentView:view];
}

In every UIViewController:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self updateViewIfIOS_7];
    UILabel* lab = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 130, 30)];
    lab.backgroundColor = [UIColor yellowColor];
    [self.contentView addSubview:lab];
    //...
}

Portrait Landscape

Gralex
  • 4,285
  • 7
  • 26
  • 47