上と下でデザインが違うUITabBarを作りたい

#こんな感じのタブバーを作りたい

![Simulator Screen Shot 2016.11.24 2.55.15.png](https://qiita-image-store.s3.amazonaws.com/0/150818/9713d8c7-835e-16af-5225-6b466a587026.png)

###やること
1. UIの実装
2. タブバーの機能実装
3. **タブバーのデザインの変更**

###実装環境
- Xcode 7.2.1
- Swift 2.2
- iOS 9.2

###参考にしたもの
[【Swift】Tab Barの使い方。タブで画面を切り替える。(Swift 2.1、XCode 7.2、Android:無、iOS:有、興奮度:C)](http://hajihaji-lemon.com/smartphone/swift/uitabbar/)
[タブバーの高さと、文字の位置・大きさを変えて、文字だけのタブバーを作る](http://qiita.com/tsugita/items/ce24aa67e4016376b9db)
[Cocoaの日々: UIAppearance で色や画像を変える](http://cocoadays.blogspot.jp/2011/10/uiappearance.html)

## 1.UIの実装
この部分はStoryBoardで作成すればいいのでさっくり。(詳しいことは[こちらのサイト](http://hajihaji-lemon.com/smartphone/swift/uitabbar/)に書いてある)

![スクリーンショット 2016-11-24 1.06.17.png](https://qiita-image-store.s3.amazonaws.com/0/150818/3ac44271-f9e8-fe75-19ff-e5a810906bb1.png)

こんな感じにした。
ポイントはUITabBarControllerは使わず、UITabBarを使って実装している。
**UITabBarItemのTagに数字を入力するのを忘れないようにすること。**
このTagを使って切り替え機能を実装していく。

## 2.タブバーの機能実装
タブバー自体の動きは簡単。
UITabBarのボタン押して、ContainerViewの表示非表示を切り替えるだけである。
ただし、今回はTabBarを2つ扱うので、ViewControllerを二つ実装する必要がある。

```swift:TabBar1ViewController.swift
class TabBar1ViewController: UIViewController, UITabBarDelegate {
    
    @IBOutlet weak var tabBar: UITabBar!
    @IBOutlet weak var view1: UIView!
    @IBOutlet weak var view2: UIView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        tabBar.delegate = self;
        
        view1.hidden = false;
        view2.hidden = true;
    }
    
    func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem) {
        if(item.tag == 1){
            view1.hidden = false;
            view2.hidden = true;
        }else if(item.tag == 2){
            view1.hidden = true;
            view2.hidden = false;
        }
    }
}
```

参考:[【Swift】Tab Barの使い方。タブで画面を切り替える。(Swift 2.1、XCode 7.2、Android:無、iOS:有、興奮度:C)](http://hajihaji-lemon.com/smartphone/swift/uitabbar/)

同様のものをもう一つ作成し、両方のタブバーで切り替えられるようにする。
ここまでで機能そのものは完成した。

## 3.タブバーのデザインの変更
今回は上部のタブバーのみで文字のみの表示を行いたいのだが、ひとまず、文字を大きくして表示位置を変えてみる。

```swift:TabBar1ViewController.swift
//タブバーアイテムのデザイン変更
UITabBarItem.appearance().setTitleTextAttributes([
    NSFontAttributeName: UIFont.systemFontOfSize(20), //文字の大きさを変更
    NSForegroundColorAttributeName: UIColor(red: 0.55, green: 0.55, blue: 0.55, alpha: 1.0) //文字の色を変更
    ], forState: UIControlState.Normal); //通常時
UITabBarItem.appearance().setTitleTextAttributes([
    NSForegroundColorAttributeName: UIColor(red: 0.55, green: 0.55, blue: 0.80, alpha: 1.0) //文字の色を変更
    ], forState: UIControlState.Selected); //選択時
UITabBarItem.appearance().titlePositionAdjustment = UIOffsetMake(0, -9); //文字の場所を移動
```

参考:[タブバーの高さと、文字の位置・大きさを変えて、文字だけのタブバーを作る](http://qiita.com/tsugita/items/ce24aa67e4016376b9db)

結果は次の通りだ。
![Simulator Screen Shot 2016.11.24 2.09.26.png](https://qiita-image-store.s3.amazonaws.com/0/150818/25833b28-21ac-81ca-2d61-3459a023180e.png)

上部のタブバーはきれいに表示されているが、変更するつもりのない下部のタブバーまで変更されてしまった。
UITabBarItem全体に変更の影響が出るようになっているようだ。
どうにかして片方だけに影響を与えることができないものか……。
いろいろ探しているうちに下のようなブログ記事を見つけた。
[Cocoaの日々: UIAppearance で色や画像を変える](http://cocoadays.blogspot.jp/2011/10/uiappearance.html)

こちらによれば、appearanceWhenContainedIn:(Objective-Cの場合, Swiftの場合はappearanceWhenContainedInInstancesOfClasses:)というメソッドで所属ビューを指定することができるらしい。
やり方も書いてあるので、早速試してみる。

```swift:TabBar1ViewController.swift
//タブバーアイテムのデザイン変更
UITabBarItem.appearanceWhenContainedInInstancesOfClasses([UITabBar.self]).setTitleTextAttributes([
    NSFontAttributeName: UIFont.systemFontOfSize(20), //文字の大きさを変更
    NSForegroundColorAttributeName: UIColor(red: 0.55, green: 0.55, blue: 0.55, alpha: 1.0) //文字の色を変更
    ], forState: UIControlState.Normal); //通常時
UITabBarItem.appearanceWhenContainedInInstancesOfClasses([UITabBar.self]).setTitleTextAttributes([
    NSForegroundColorAttributeName: UIColor(red: 0.55, green: 0.55, blue: 0.80, alpha: 1.0) //文字の色を変更
    ], forState: UIControlState.Selected); //選択時
UITabBarItem.appearanceWhenContainedInInstancesOfClasses([UITabBar.self]).titlePositionAdjustment = UIOffsetMake(0, -9); //文字の場所を移動
```

appearence()をappearanceWhenContainedInInstancesOfClasses([UITabBar.self])へ変換。

![Simulator Screen Shot 2016.11.24 2.46.26.png](https://qiita-image-store.s3.amazonaws.com/0/150818/94509946-6ddb-b382-7019-74327f5e2c5b.png)

結果がこちら。
残念ながら変わったように見えない。
ここで気がついた。
UITabBarItemはどちらもUITabBarに入っているのだから、今の変更は適用されて当然であった。

##4.クラスを作る。
原因に気がついたので、入れられているUITabBarの方のクラスを変更すれば、変更が可能なのではないか、と気づいた。
というわけで、UITabBarのサブクラスを作る。

```swift:CustomTabBar.swift
import Foundation
import UIKit

class CustomTabBar: UITabBar {
    
}
```

appearanceで指定するときの親要素が欲しいだけだから、中に何か書く必要はない。
上部タブバーのclassをCustomTabBarに変更し、appearanceWhenContainedInInstancesOfClasses:の引数をCustomTabBar.selfにしてやる。

![Simulator Screen Shot 2016.11.24 2.55.15.png](https://qiita-image-store.s3.amazonaws.com/0/150818/9713d8c7-835e-16af-5225-6b466a587026.png)

上部のタブバーだけにデザイン変更が効くようになった。

##5.まとめ
TabBarのサブクラスを作れば、比較的簡単にデザインが異なる複数のタブバーを設置することが可能なようだ。
自分が次に困らないようにと作ったものだが、他の誰かの役に立ってくれたら嬉しい。

###サンプルコード
[GitHub SwiftSample/DoubleTabBar](https://github.com/mi-snow/SwiftSample/tree/master/DoubleTabBar)

###参考文献
[【Swift】Tab Barの使い方。タブで画面を切り替える。(Swift 2.1、XCode 7.2、Android:無、iOS:有、興奮度:C)](http://hajihaji-lemon.com/smartphone/swift/uitabbar/)
[タブバーの高さと、文字の位置・大きさを変えて、文字だけのタブバーを作る](http://qiita.com/tsugita/items/ce24aa67e4016376b9db)
[Cocoaの日々: UIAppearance で色や画像を変える](http://cocoadays.blogspot.jp/2011/10/uiappearance.html)
[appearanceWhenContainedInInstancesOfClasses: - UIAppearance | Apple Developer Documentation](https://developer.apple.com/reference/uikit/uiappearance/1615013-appearancewhencontainedininstanc?language=objc)