Xcode
iOS

ios7のnavigationbarをios6以前のデザインに合わせる方法

More than 5 years have passed since last update.

ios6 → ios7対応をする際にios6のデザインで対応する際の覚え書き


レイアウト崩れ


原因は、ほぼこれ


In iOS 7, view controllers use full-screen layout. At the same time, iOS 7 gives you more granular control over the way a view controller lays out its views. In particular, the concept of full-screen layout has been refined to let a view controller specify the layout of each edge of its view.


https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TransitionGuide/AppearanceCustomization.html#//apple_ref/doc/uid/TP40013174-CH15-SW1


全体的に上部に寄ってしまっているのを対処

xcode4.pngxcode5.png

xcode4で作成したアプリをxcode5で見ると全体的に上部に寄ってしまう。


 Storyboardでの修正


  1. Storyboard上で対象のViewControllerを選択する

  2. Cmd+Alt+4でAttributes Inspectorを開く

  3. Under Top Barsをオフにする

attributes_inspector.png


コードでの修正

- (void)viewDidLoad

{
[super viewDidLoad];
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
self.edgesForExtendedLayout = UIRectEdgeNone;
}
}


結果

result.png


StoryBoardで作成したモーダル画面のnavigationbarがstatusbarと重なるのを対処

modal_navi.png

これは正しくnavigation barを使っていないために起こる

(モーダルは関係なくて、Storyboardを分割して運用する場合に起きやすい間違い)

Storyboard上でnavigation barを置く場合は、以下のようにする

1. ViewControllerを配置

2. メニューのEditor → Embed in → Navigation Controllerを選択

左図がEmbed inで作成していない場合、右図がEmbed inで作成している場合

wrong_navi.pngcorrect_navi.png


結果

result_correct_navi.png


navigationbarでbackground画像を利用している場合にデザインが崩れるときの対処

基本的に以下のページのTable 5-1に合わせて画像を作成すれば問題ない

https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TransitionGuide/Bars.html#//apple_ref/doc/uid/TP40013174-CH8-SW1

高さ45ポイント以上の画像をバックグラウンドに置くと以下のように超えた分が引き延ばされる(以下の画像は高さ45pxで1px緑の線を引いた画像)

スクリーンショット 2013-09-25 13.55.08.png


44ポイントの画像を用意して対処

navi_44.png


64ポイントの画像を用意して対処

navi_64.png

この場合は、ios6でも64ポイントのnavigationbarになってしまうので、44と64の両方の画像を用意して制御する

    if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {

[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed: @"navi_background"] forBarMetrics:UIBarMetricsDefault];
}else{
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed: @"navi_background_ios7"] forBarMetrics:UIBarMetricsDefault];
}


ボタンをios7のデフォルトにしたくない

これはボタンを画像にすることで解決できる


戻るボタンをios6のように表示したい

戻るボタン用にこんな画像を用意

back_btn_on.png

ただし、以下のように書いても、ios7.0で何故か最初の表示時に画像が表示されない

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

{
・・・・
UIImage* backImageOff = [UIImage imageNamed:@"back_btn_off.png"];
UIImage* backImageOn = [UIImage imageNamed:@"back_btn_on.png"];

backImageOff = [backImageOff stretchableImageWithLeftCapWidth: 15.0 topCapHeight: 30.0];
backImageOn = [backImageOn stretchableImageWithLeftCapWidth: 15.0 topCapHeight: 30.0];

[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backImageOff forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backImageOn forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(6.2, 0) forBarMetrics:UIBarMetricsDefault];

return YES;
}


解決

それぞれのストーリーで画像を設定する

- (void)viewDidLoad

{
UIImage* backImageOff = [UIImage imageNamed:@"back_btn_off.png"];
UIImage* backImageOn = [UIImage imageNamed:@"back_btn_on.png"];

backImageOff = [backImageOff stretchableImageWithLeftCapWidth: 15.0 topCapHeight: 30.0];
backImageOn = [backImageOn stretchableImageWithLeftCapWidth: 15.0 topCapHeight: 30.0];

[self.navigationItem.backBarButtonItem setBackButtonBackgroundImage:backImageOff forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[self.navigationItem.backBarButtonItem setBackButtonBackgroundImage:backImageOn forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault];
}

さらに

ストーリーボードの対象のNavitation ItemのAttribute InspectorのBack Buttonに文字を入れる(これをコードで記述しても動作しなかった)

back.title.png

あとはTint Colorがios7では青がデフォルトに変わったので、自分で設定する

    [[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];