酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Swiftでタブバーにバッジを点灯させる/タブバーの部分に任意のUIViewを表示させる

iOSアプリでタブバーにバッヂを点灯させてみましょう。また消灯させる方法についても紹介します。

標準のバッヂはモサっとしていて嫌だと思う方もいるかもしれません。カスタマイズさせることを厭わない方向けに、タブバーの部分に任意のUIViewを表示させる方法も紹介します。

タブバーにバッジをつける

タブバーのバッジを普通に表示したい場合は、badgeValueに表示したい文言を設定します。

多くの場合、バッジには数値を表示すると思います。Int型の数値を表示させる場合にはString型に変換してからbadgeValueに設定します。

@IBAction func button1Action(sender: AnyObject) {
    tabBarItem.badgeValue = "1"
}

タブバーに表示できるのはString型の文字列です。任意の文言を設定することができる。下記のサンプルコードではNewをバッジに指定しています。

@IBAction func button2Action(sender: AnyObject) {
    self.tabBarController?.viewControllers?[1].tabBarItem.badgeValue = "New"
}

前述したコードを実行させると下図のようになります。

f:id:ch3cooh393:20160503000038p:plain

バッジを外したい時はnilを指定します。

@IBAction func button3Action(sender: AnyObject) {
    tabBarItem.badgeValue = nil
}

タブバー(UITabBarItem)に任意のViewを追加する

タブバーに任意のViewを表示してみましょう。

UITabBarItemはUIViewを継承していないのでdrawRectをoverrideして独自に描画することができません。

しかし、viewを持っていないわけではないです。以下のようにviewを取得することができます。

let v = self.valueForKey("view") as? UIView

UITabBarItemのviewを取得できるということは、addSubViewで任意のUIViewを追加することができます。

UITabBarItemのextensionを追加して、単にUIViewを追加するだけのaa_addSubViewというメソッドを追加します。

引数のUIViewをタブバーアイテムのviewに対して追加するだけの簡単な実装です。

extension UITabBarItem {

    func aa_addSubView(view: UIView) {
        guard let v = self.valueForKey("view") as? UIView else {
            return
        }
        
        v.addSubview(view)
    }
   
}

aa_addSubViewメソッドを使って、適当なUILabelを追加してみましょう。わかりやすいように背景色にマゼンタを指定します。

@IBAction func button4Action(sender: AnyObject) {
    let label = UILabel(frame: CGRectMake(0, 0, 50, 30))
    label.text = "label"
    label.backgroundColor = UIColor.magentaColor()
        
    tabBarItem.aa_addSubView(label)
}

上記のコードを実行した結果は下記の通りです。

f:id:ch3cooh393:20160503002033p:plain

この方法を応用することで、タブバーのバッジとして任意の画像を表示させたりすることができるでしょう。

(応用例)タブバーに任意の画像を表示させる

標準の赤いバッヂではなく、下図の「Newデーター」画像をバッヂとして表示させてみましょう。

f:id:ch3cooh393:20160503233809p:plain

先ほどのようにUITabBarItemのextensionを追加して、バッヂ用の任意の画像を追加するだけのaa_setBadgeImageというメソッドを追加しました。

extension UITabBarItem {
    
    private static let tagBadge = 393
    
    func aa_setBadgeImage(image: UIImage?, offset: CGPoint? = nil) {
        guard let v = self.valueForKey("view") as? UIView else {
            return
        }
        
        // すでに tagBadge のViewが追加されていたら削除しておく
        for subView in v.subviews {
            if subView.tag == UITabBarItem.tagBadge {
                subView.removeFromSuperview()
            }
        }
        
        // UITabBarItemの中央に指定されたUIImageを表示させる
        if let img = image {
            let imageView = UIImageView(image: img)
            imageView.tag = UITabBarItem.tagBadge
            
            var r = imageView.frame
            r.origin.y = (v.bounds.height - r.height) / 2 + (offset?.y ?? 0)
            r.origin.x = (v.bounds.width - r.width) / 2 + (offset?.x ?? 0)
            imageView.frame = r
            
            v.addSubview(imageView)
        }
    }
}

aa_setBadgeImageメソッドはこのように使用しました。

@IBAction func button5Action(sender: AnyObject) {
    let image = UIImage(named: "new_icon")
    let offset = CGPointMake(20, -10)
    self.tabBarController?.viewControllers?[1].tabBarItem.aa_setBadgeImage(image, offset: offset)    
}

実行すると下図のように表示されます。

f:id:ch3cooh393:20160503233519p:plain