Itty Bitty Labs

Code and technical stuff from Itty Bitty Apps.

Working with iOS 6 and 7

If business reasons require you to continue supporting iOS 6, this means you may need to work with both iOS 6 and 7 for quite a while. Developers always hate this, as it may increase the code base cyclomatic complexity (e.g. if iOS 6 do this, else if iOS 7 do that…) . I love it, since my wife, mum, dad and manager are still using iOS 6.

Layout issue on iOS 7

Here is a very simple app running on iOS 6.

After switch the simulator to iOS 7, the label is missing

Why? Let’s reveal it.

The label is actually behind the NavigationBar. In iOS 7, apple introduced a new property called [UIViewController setEdgesForExtendedLayout:] and the default value is UIRectEdgeAll. When your container is navigation controller, the default layout will start from the top of navigation bar. This is why all of the UI elements had been shift up 44pt.

A quick way to fix this issue is add the following snippet to method - (void)viewDidLoad.

Fix Layout issue
1
self.edgesForExtendedLayout = UIRectEdgeNone;

Now, it’s been fixed.

iOS 6 runtime exception

Let’s run the app on iOS 6 then, we found the following runtime exception.

iOS 6 runtime exception
1
[LAViewController setEdgesForExtendedLayout:]: unrecognized selector sent to instance 0x778a210

All iOS 7 only API invokes need to be wrapped with proper guarder.

1
2
3
4
if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)])
{
    self.edgesForExtendedLayout = UIRectEdgeNone;
}

Xcode 4 compile error

Some machines might still running with a Xcode 4.6. When they pull the latest code, they will fail to compile then.

1
2
Property 'edgesForExtendedLayout' not found on object of type 'LAViewController *'
Use of undeclared identifier 'UIRectEdgeNone'

To avoid the compile stage error, we need to create the following macro.

1
2
3
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
#define IOS7_SDK_AVAILABLE 1
#endif

Then wrap the iOS 7 code path if needed.

1
2
3
#ifdef IOS7_SDK_AVAILABLE
...
#endif

UILabel background inconsistency

As a UILabel, iOS 7 default background color is clearColor (which make sense most of the time), while the iOS 6 default value is white. So we’d better to explicit set the label background color.

1
view.backgroundColor = [UIColor clearColor];

Hide status bar while in full screen

In iOS 6, when we call presentViewController, the default modal screen will be full screen. (UIModalPresentationFullScreen). In order to achieve a consistent experience on iOS 7, we add the following code to modal controller.

1
2
3
4
- (BOOL)prefersStatusBarHidden
{
  return YES;
}

[UIToolbar barStyle]

We used UIToolbar with the system keyboard (Actually, it’s IBAForms and EZForm using them). As the iOS 6 keyboard is in dark skin, people style the toolbar like this.

1
self.barStyle = UIBarStyleBlack;// or UIBarStyleBlackTranslucents

Coming to iOS 7, the keyboard skin becomes lighter, so we need different barStyle for various iOS version.

1
2
3
4
5
6
7
8
if ([[[UIDevice currentDevice] systemVersion] compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending)
{
    self.barStyle = UIBarStyleDefault;
}
else
{
    self.barStyle = UIBarStyleBlack;//or UIBarStyleBlackTranslucent
}

More than that…

It is definitely more than that. The above tips are just some of the most common issues I have seen when working on iOS 6 & 7 codebases.


About Long

Long Sun is an iOS Developer at Itty Bitty Apps. He has worked on the iOS introspection tool Reveal and Realcommercial iPhone/iPad App. You can follow him on twitter @spritesun