January 9, 2014

iOS 6 & 7 Compatibility Tips

By

In just a few months iOS 7 has found its way to over 80% of all iOS devices. Xamarin announced same day support when iOS 7 launched and it is easy to upgrade your app when developing with Xamarin.iOS. Apple recommends first redesigning your app for iOS 7, and then if you have structural or navigational changes to bring them over to the iOS 6 version where they are appropriate. Apple does not recommend restyling your iOS 6 version of your app with iOS 7 design elements such as borderless bar buttons. Here are a few quick user interface tips to help you with your transition and compatibility.

iOS6and7

Version Numbers:

Determining the version of iOS is important when you are accessing new APIs. If you attempt to call an iOS 7 API on a device running an older version this may cause your application to crash if it is not handled properly. So it is important to always check for the correct version number by using this simple helper method:

UIDevice.CurrentDevice.CheckSystemVersion (7, 0);

To make it easier you can make this a static method in a utility class. I called mineĀ Util.cs and added the following method to check if the current device is iOS 7 or newer.

public static bool IsiOS7 {
  get { return UIDevice.CurrentDevice.CheckSystemVersion (7, 0); }
}

This will allow you to make specific calls based on the OS version:

if(Util.IsiOS7) {
  //Call iOS 7 API
} else {
  //Call iOS 6.1 or earlier API
}

Loading Resources:

In some cases you may need to load different resources or assets for older versions of iOS. In iOS 7 icons follow a thin design style compared to older versions of iOS. To ensure that your users have the correct icons based on their version you might consider tagging all of your iOS specific assets with a prefix such as “ios7_”. This will allow you to load icons conditionally such as adding a UIBarButtonItem to the NavigationBar:

var imageResource = Util.IsiOS7 ? "ios7_search" : "search";
var searchImage = UIImage.FromBundle (imageResource);
var barbutton = new UIBarButtonItem (searchImage, UIBarButtonItemStyle.Plain, null);

ResourceLoading

Additionally you could create a helper method to return the correct name

//Helper Method
public static string GetIcon(string resourceName){
  return IsiOS7 ? "ios7_" + resourceName : resourceName;
}
//Usage
var searchImage = UIImage.FromBundle (Util.GetIcon("search"));
var barbutton = new UIBarButtonItem (searchImage, UIBarButtonItemStyle.Plain, null);

View Controller Changes:

Views in iOS 7 use full-screen layouts, if you are currently specifying WantsFullScreenLayout = true, the view controller may display its content at an unexpected screen location when it runs on iOS 7. However you can adjust how a view controller lays out its views. All UIViewController’s provide these properties:

EdgesForExtendedLayout:
If you have created custom UIViewControllers this is going to be your new best friend. Since iOS 7 UIViewControls now go under the NavigationBar. It is common that your user interface might be hiding under it. Setting this property to UIRectEdge.None will force iOS 7 to not put your content under the NavigationBar.

ExtendedLayoutIncludesOpaqueBars:
If you are using opaque bars you should set not only EdgesForExtendedLayout, but you should also set ExtendedLayoutIncludesOpaqueBars to true, as the default value is false.

AutomaticallyAdjustsScrollViewInsets:
ScrollViews now automatically adjust their insets in iOS 7. If you do not desire this you will want to set this property to false.

For all of these you should ensure that you are wrapping the properties in a version check:

if(Util.IsiOS7) {
  EdgesForExtendedLayout = UIRectEdge.None;
}

EdgesForExtendedLayout

Controls:

There have be several changes to the look and feel of controls in iOS 7. Here are a few quick tips:

UIButtons:
In iOS 7 a UIButton no longer include a bezel or background appearance. UIButtonType.RoundedRect is now defined as UIButtonType.System. However if you need to still target earlier versions continue using RoundRect and iOS 7 will still apply the System button appearance. If your user interface requires a background you can approach it in one of two ways.

1.) Specify a background color: button.Background = UIColor.DarkGray;
2.) Use a button of type UIButtonType.Custom and supply a custom background image.

UIButton

UIBarButtons:
In iOS 7 custom bar button art is no longer treated as a template image, which is used as a mask to create the final image. This means that the tint of the Window or Navigation bar will be applied. To specify whether custom art should be treated as a template image or fully be rendered use the following properties:

var image = UIImage.FromBundle('search');
if(Util.IsiOS7) {
//The image should be treated as a template image and will use tinting.
image = image.ImageWithRenderingMode (UIImageRenderingMode.AlwaysTemplate);
or
//The image should be rendered as is, no tint applied
image = image.ImageWithRenderingMode (UIImageRenderingMode.AlwaysOriginal);
}
var barbutton = new UIBarButtonItem (image, UIBarButtonItemStyle.Plain, null);

Tinting:

In iOS 6 and earlier you were able to tint many bar backgrounds using:

TintColor = UIColor.DarkGray;

However in iOS 7 there is a new property, BarTintColor, that is used to tint the bar background, while TintColor is now used to tint the bar button items.

if(Util.IsiOS7) {
  bar.BarTintColor = UIColor.DarkGray; //bar background
  bar.TintColor = UIColor.Red; //Tint color of button items
}
else{
  bar.TintColor = UIColor.DarkGray; //bar background
}

BarTintColor

Just like the UINavigationBar the following controls also have a new BarTintColor that you can use:

  • UISearchBar
  • UIScopeBar
  • UITabBar
  • UIToolbar

For any of these bars you should follow this same practice of checking the version:

if (Util.IsiOS7) {
  toolbar.BarTintColor = UIColor.DarkGray;
} else {
  toolbar.TintColor = UIColor.DarkGray;
}

These are just a few quick tips to get you moving towards iOS 7 and keeping your application fully backwards compatible with older versions of iOS. The full source code for this sample is available on GitHub.

Discuss this blog post in the Xamarin Forums

TwitterFacebookGoogle+LinkedInEmail