20
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

小ネタ:UITabBarControllerに「モーダル表示するボタン」を追加する(Swift)

Last updated at Posted at 2015-07-10

tabbar.gif

iOSアプリで、「タブバーにタブバーっぽくないアイコンを置いて、それをタップしたら画面がモーダル出てくる」というのを見かけます。それをSwiftでやってみたという小ネタです。

ポイント:

  • UITabBarControllerを継承したクラスを作る
  • 押したらモーダル表示する、というボタンをself.tabBarにaddSubviewしておく
  • UITabBarの中のボタンは、subviewsの中で、クラスが"UITabBarButton"のものなので、ボタンの表示位置はこれを使って調整する
  • UITabBarButtonは非公開クラスなので、クラス名を文字列でチェックしている。
class MyTabBarController:UITabBarController{
    let button:UIButton = UIButton()
    
    override func viewDidLoad() {
        // タブバーに重ねるボタンを作成
        // ここではサイズとか位置は気にしない。
        let image = UIImage(named: "button")
        self.button.setBackgroundImage(image, forState: .Normal)
        self.button.addTarget(self, action: "openModal",
            forControlEvents: UIControlEvents.TouchUpInside)
        
        // self.view ではなくて、self.tabBar にaddSubviewする
        self.tabBar.addSubview(self.button)
     }
    
    // 表示される直前にここが呼ばれるので
    // ここでself.buttonの位置を調整する
    override func viewDidLayoutSubviews() {
        // タブバーのn番目にあるUIViewを取得してくる。
        // self.tabBarButtons()は、下のextensionで追加してるメソッド
//        let v = self.tabBarButtons().first // 左端タブのUIViewn
        let v = self.tabBarButtons().last  // 右端タブのUIView
//        let v = self.tabBarButtons()[1]   // 2番目のタブの位置
        if let v = v {
            button.frame = v.frame
        }
    }
    
    // ボタンおされたらモーダル表示
    func openModal(){
        // モーダル表示するViewControllerは、Storyboardから拾ってくる。
        let vc = self.storyboard?.instantiateViewControllerWithIdentifier("ModalViewController") as? UIViewController
        if let vc = vc {
            self.presentViewController(vc, animated: true, completion: nil)
        }
    }
}

// UITabBarControllerを拡張
extension UITabBarController{
    // タブバーを構成している、内部クラスの「UITabBarButton」を探してきて、UIViewの配列として返す。
    // OSのバージョンアップで使えなくなる可能性がある。
    func tabBarButtons()->[UIView]{
	// reduce関数は知らなければ損。
        return self.tabBar.subviews.reduce([], combine: { (ret:[UIView], item:AnyObject) -> [UIView] in
            if let v = item as? UIView  {
                // ここ、クラス判定を「文字列」でやってるから、裏技ちっく。
                if v.isKindOfClass(NSClassFromString("UITabBarButton")) {
                    return ret + [v]
                }
            }
            return ret
        })
    }
}

ちゃんと作るなら、

  • 画像をちゃんと作らないと、タブバーから浮いて見えたり、背景文字が見えてしまったりする(特にサイズ違いの実機で要テスト)
  • ボタンを重ねたTabBarItemは死にアイテムになるので、意味のある画面は配置しないようにする
  • OSのバージョンアップ時にはテスト厚く
    等など、気をつけましょう。
20
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?