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


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.png](https://qiita-image-store.s3.amazonaws.com/0/10494/9d3be5ce-c1fd-19b8-5252-e709bb9d0163.png "xcode4.png")![xcode5.png](https://qiita-image-store.s3.amazonaws.com/0/10494/7d067c16-60f8-19f6-99cd-5c2f51fcc928.png "xcode5.png")


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


###　Storyboardでの修正

1. Storyboard上で対象のViewControllerを選択する
2.  Cmd+Alt+4でAttributes Inspectorを開く
3. Under Top Barsをオフにする

![attributes_inspector.png](https://qiita-image-store.s3.amazonaws.com/0/10494/c4944c93-a7ed-73bc-89bb-eb9a302d64c3.png "attributes_inspector.png")


### コードでの修正

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

### 結果
![result.png](https://qiita-image-store.s3.amazonaws.com/0/10494/9b993408-d548-60f2-8c69-3439e2faa0a6.png "result.png")



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

![modal_navi.png](https://qiita-image-store.s3.amazonaws.com/0/10494/b31854d1-1f12-22b7-073d-9d25d33ad8b8.png "modal_navi.png")
これは正しくnavigation barを使っていないために起こる
(モーダルは関係なくて、Storyboardを分割して運用する場合に起きやすい間違い)

 Storyboard上でnavigation barを置く場合は、以下のようにする
1. ViewControllerを配置
2. メニューのEditor →　Embed in →　Navigation Controllerを選択

左図がEmbed inで作成していない場合、右図がEmbed inで作成している場合
![wrong_navi.png](https://qiita-image-store.s3.amazonaws.com/0/10494/051ddc67-84b9-c397-0d7c-f4563a04d3c0.png "wrong_navi.png")![correct_navi.png](https://qiita-image-store.s3.amazonaws.com/0/10494/48caefbf-6ece-df1e-74cd-e3d4b1a46bd3.png "correct_navi.png")

### 結果
![result_correct_navi.png](https://qiita-image-store.s3.amazonaws.com/0/10494/97a4a52b-193e-00bb-341f-838c6d43fbc6.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](https://qiita-image-store.s3.amazonaws.com/0/10494/eb68fc19-a97a-0e64-9354-34f498594eef.png "スクリーンショット 2013-09-25 13.55.08.png")

### 44ポイントの画像を用意して対処
![navi_44.png](https://qiita-image-store.s3.amazonaws.com/0/10494/07c651f0-55a8-93f4-d906-691587bef0b0.png "navi_44.png")

### 64ポイントの画像を用意して対処
![navi_64.png](https://qiita-image-store.s3.amazonaws.com/0/10494/ac8d31e7-ae46-487e-a522-d62f22bffd45.png "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](https://qiita-image-store.s3.amazonaws.com/0/10494/1f99dd5f-c054-dcfa-cde4-566d16a3b778.png "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](https://qiita-image-store.s3.amazonaws.com/0/10494/9a4d0872-fe03-f997-26ae-968e76f16a45.png "back.title.png")


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

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