web-dev-qa-db-ja.com

UITabBarItemバッジの色を変更することは可能ですか

UITabBarItembadgeの背景色を変更したいのですが、作成方法に関するリソースが見つかりません。

enter image description here

30
1110

UITabBarItemはiOS 10以降で利用できます。

var badgeColor: UIColor? { get set }

また、外観を介して利用できます。

if #available(iOS 10, *) {
   UITabBarItem.appearance().badgeColor = .green
}

リファレンスドキュメント: https://developer.Apple.com/reference/uikit/uitabbaritem/1648567-badgecolor

29
Nuno Gonçalves

バッジの色の変更は、iOS 10以降でbadgeColor内のUITabBarItemプロパティを使用してネイティブにサポートされるようになりました。プロパティの詳細については Apple docs を参照してください。

例:

  • スウィフト3:myTab.badgeColor = UIColor.blue
  • Objective-C:[myTab setBadgeColor:[UIColor blueColor]];
13
Hans Knöchel

私は自分のアプリ用にこのコードを書きましたが、iOS 7でのみテストしました。

for (UIView* tabBarButton in self.tabBar.subviews) {
    for (UIView* badgeView in tabBarButton.subviews) {
        NSString* className = NSStringFromClass([badgeView class]);

        // looking for _UIBadgeView
        if ([className rangeOfString:@"BadgeView"].location != NSNotFound) {
            for (UIView* badgeSubview in badgeView.subviews) {
                NSString* className = NSStringFromClass([badgeSubview class]);

                // looking for _UIBadgeBackground
                if ([className rangeOfString:@"BadgeBackground"].location != NSNotFound) {
                    @try {
                        [badgeSubview setValue:[UIImage imageNamed:@"YourCustomImage.png"] forKey:@"image"];
                    }
                    @catch (NSException *exception) {}
                }

                if ([badgeSubview isKindOfClass:[UILabel class]]) {
                    ((UILabel *)badgeSubview).textColor = [UIColor greenColor];
                }
            }
        }
    }
}

バッジの背景は、色ではなく画像でのみ更新できます。何らかの方法で更新したい場合は、バッジラベルも公開しました。

このコードは、tabBarItem.badgeValue!の設定後に呼び出す必要があることに注意することが重要です。

編集:4/14/14

上記のコードは、どこから呼び出されてもiOS 7で機能します。 iOS 7.1で動作させるには、ビューコントローラー-viewWillLayoutSubviewsで呼び出します。

編集:12/22/14

これは私が現在使用している更新されたスニペットです。簡単にするために、コードをカテゴリ拡張に配置しました。

- (void)badgeViews:(void (^)(UIView* badgeView, UILabel* badgeLabel, UIView* badgeBackground))block {
    if (block) {
        for (UIView* tabBarButton in self.subviews) {
            for (UIView* badgeView in tabBarButton.subviews) {
                NSString* className = NSStringFromClass([badgeView class]);

                if ([className rangeOfString:@"BadgeView"].location != NSNotFound) {
                    UILabel* badgeLabel;
                    UIView* badgeBackground;

                    for (UIView* badgeSubview in badgeView.subviews) {
                        NSString* className = NSStringFromClass([badgeSubview class]);

                        if ([badgeSubview isKindOfClass:[UILabel class]]) {
                            badgeLabel = (UILabel *)badgeSubview;

                        } else if ([className rangeOfString:@"BadgeBackground"].location != NSNotFound) {
                            badgeBackground = badgeSubview;
                        }
                    }

                    block(badgeView, badgeLabel, badgeBackground);
                }
            }
        }
    }
}

それを呼び出す準備ができると、次のようになります。

[self.tabBar badgeViews:^(UIView *badgeView, UILabel *badgeLabel, UIView *badgeBackground) {

}];

編集:11/16/15

一部の人々はこのコードで何が起こっているかについてもう少し明確にする必要があることが私の注意にもたらされました。 forループは、公開されていないいくつかのビューを検索しています。ビューのクラス名に予期された名前の一部が含まれているかどうかを確認することにより、意図したビューに確実に到達する一方で、Appleによる可能性のあるレッドフラグを立てないようにします。すべてが見つかると、これらのビューに簡単にアクセスできるブロックが実行されます。

このコードが将来のiOSアップデートで機能しなくなる可能性があることは注目に値します。たとえば、これらの内部ビューはいつか異なるクラス名を取得する可能性があります。ただし、内部でApple=がクラスをこの性質にリファクタリングすることはめったにないので、その可能性はほとんどありません。しかし、そうしたとしても、UITabBarBadgeView 、これはまだコードの予想されるポイントに到達します。iOS9は十分に機能しているため、このコードは意図したとおりに機能しているため、この問題が発生することはありません。

12
cnotethegr8

私は同じ問題を抱えており、BadgeViewを簡単にカスタマイズできるUILabelに置き換える小さなカテゴリを作成することで解決しました。

https://github.com/enryold/UITabBarItem-CustomBadge/

10
eold

Swiftを使用している人のために、バッジビューを任意の画面サイズと任意の向きで機能させるために、TimWhitingの回答を改善することができました。

 extension UITabBarController {

    func setBadges(badgeValues: [Int]) {

        for view in self.tabBar.subviews {
            if view is CustomTabBadge {
                view.removeFromSuperview()
            }
        }

        for index in 0...badgeValues.count-1 {
            if badgeValues[index] != 0 {
                addBadge(index, value: badgeValues[index], color:UIColor(paletteItem: .Accent), font: UIFont(name: Constants.ThemeApp.regularFontName, size: 11)!)
            }
        }
    }

    func addBadge(index: Int, value: Int, color: UIColor, font: UIFont) {
        let badgeView = CustomTabBadge()

        badgeView.clipsToBounds = true
        badgeView.textColor = UIColor.whiteColor()
        badgeView.textAlignment = .Center
        badgeView.font = font
        badgeView.text = String(value)
        badgeView.backgroundColor = color
        badgeView.tag = index
        tabBar.addSubview(badgeView)

        self.positionBadges()
    }

    override public func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        self.positionBadges()
    }

    // Positioning
    func positionBadges() {

        var tabbarButtons = self.tabBar.subviews.filter { (view: UIView) -> Bool in
            return view.userInteractionEnabled // only UITabBarButton are userInteractionEnabled
        }

        tabbarButtons = tabbarButtons.sort({ $0.frame.Origin.x < $1.frame.Origin.x })

        for view in self.tabBar.subviews {
            if view is CustomTabBadge {
                let badgeView = view as! CustomTabBadge
                self.positionBadge(badgeView, items:tabbarButtons, index: badgeView.tag)
            }
        }
    }

    func positionBadge(badgeView: UIView, items: [UIView], index: Int) {

        let itemView = items[index]
        let center = itemView.center

        let xOffset: CGFloat = 12
        let yOffset: CGFloat = -14
        badgeView.frame.size = CGSizeMake(17, 17)
        badgeView.center = CGPointMake(center.x + xOffset, center.y + yOffset)
        badgeView.layer.cornerRadius = badgeView.bounds.width/2
        tabBar.bringSubviewToFront(badgeView)
    }
}

class CustomTabBadge: UILabel {}
10
Kirualex

Swift Swift 3。

extension UITabBarController {

    func setBadges(badgeValues: [Int]) {

        for view in self.tabBar.subviews {
            if view is CustomTabBadge {
                view.removeFromSuperview()
            }
        }

        for index in 0...badgeValues.count-1 {
            if badgeValues[index] != 0 {
                addBadge(index: index, value: badgeValues[index], color: UIColor.blue, font: UIFont(name: "Helvetica-Light", size: 11)!)
            }
        }
    }

    func addBadge(index: Int, value: Int, color: UIColor, font: UIFont) {
        let badgeView = CustomTabBadge()

        badgeView.clipsToBounds = true
        badgeView.textColor = UIColor.white
        badgeView.textAlignment = .center
        badgeView.font = font
        badgeView.text = String(value)
        badgeView.backgroundColor = color
        badgeView.tag = index
        tabBar.addSubview(badgeView)

        self.positionBadges()
    }

    override open func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        self.positionBadges()
    }

    // Positioning
    func positionBadges() {

        var tabbarButtons = self.tabBar.subviews.filter { (view: UIView) -> Bool in
            return view.isUserInteractionEnabled // only UITabBarButton are userInteractionEnabled
        }

        tabbarButtons = tabbarButtons.sorted(by: { $0.frame.Origin.x < $1.frame.Origin.x })

        for view in self.tabBar.subviews {
            if view is CustomTabBadge {
                let badgeView = view as! CustomTabBadge
                self.positionBadge(badgeView: badgeView, items:tabbarButtons, index: badgeView.tag)
            }
        }
    }

    func positionBadge(badgeView: UIView, items: [UIView], index: Int) {

        let itemView = items[index]
        let center = itemView.center

        let xOffset: CGFloat = 12
        let yOffset: CGFloat = -14
        badgeView.frame.size = CGSize(width: 17, height: 17)
        badgeView.center = CGPoint(x: center.x + xOffset, y: center.y + yOffset)
        badgeView.layer.cornerRadius = badgeView.bounds.width/2
        tabBar.bringSubview(toFront: badgeView)
    }
}

class CustomTabBadge: UILabel {}

いいえ、色を変更することはできませんが、代わりに独自のバッジを使用できます。この拡張子をファイルスコープに追加すると、バッジを好きなようにカスタマイズできます。ルートビューコントローラのいずれかでself.tabBarController!.setBadges([1,0,2])を呼び出すだけです。

明確にするために、3つの項目があり、バッジの値が左から右に表示されるタブバーの場合です。

extension UITabBarController {
    func setBadges(badgeValues:[Int]){

        var labelExistsForIndex = [Bool]()

        for value in badgeValues {
            labelExistsForIndex.append(false)
        }

        for view in self.tabBar.subviews {
            if view.isKindOfClass(PGTabBadge) {
                let badgeView = view as! PGTabBadge
                let index = badgeView.tag

                if badgeValues[index]==0 {
                    badgeView.removeFromSuperview()
                }

                labelExistsForIndex[index]=true
                badgeView.text = String(badgeValues[index])

            }
        }

        for var i=0;i<labelExistsForIndex.count;i++ {
            if labelExistsForIndex[i] == false {
                if badgeValues[i] > 0 {
                    addBadge(i, value: badgeValues[i], color:UIColor(red: 4/255, green: 110/255, blue: 188/255, alpha: 1), font: UIFont(name: "Helvetica-Light", size: 11)!)
                }
            }
        }


    }

    func addBadge(index:Int,value:Int, color:UIColor, font:UIFont){

        let itemPosition = CGFloat(index+1)
        let itemWidth:CGFloat = tabBar.frame.width / CGFloat(tabBar.items!.count)

        let bgColor = color

        let xOffset:CGFloat = 12
        let yOffset:CGFloat = -9

        var badgeView = PGTabBadge()
        badgeView.frame.size=CGSizeMake(17, 17)
        badgeView.center=CGPointMake((itemWidth * itemPosition)-(itemWidth/2)+xOffset, 20+yOffset)
        badgeView.layer.cornerRadius=badgeView.bounds.width/2
        badgeView.clipsToBounds=true
        badgeView.textColor=UIColor.whiteColor()
        badgeView.textAlignment = .Center
        badgeView.font = font
        badgeView.text = String(value)
        badgeView.backgroundColor = bgColor
        badgeView.tag=index
        tabBar.addSubview(badgeView)

    }
}

class PGTabBadge: UILabel {

}
7
TimWhiting

いいえそうです。値のみを設定できます。 Appleのドキュメントバッジから:

アイテムの右上隅にredで囲まれたテキストが表示されます。

4
RomanN

バッジの色を変更するには、インデックスでタブ項目を指定する必要があります。#iOS 10で利用可能

    if #available(iOS 10.0, *) 
    {
        self.kAppTabBarController.tabBar.items![1].badgeColor = YOUR_COLOR
    }
1
Parimal

タブバーアイテムを選択して属性インスペクターに移動することで、ストーリーボードでもそれを実行できます。

enter image description here

0
Myxtic

はい。ただし、可能な唯一の解決策は、カスタムタブバーを作成し、カスタムタブバーバッジアイコンを作成することです。カスタムタブバーを作成するための多くの記事/コードがあります。

0
JiteshW
// change TabBar BadgeView background Color
-(void)changeTabBarBadgeViewBgColor:(UITabBar*)tabBar {
    for (UIView* tabBarButton in tabBar.subviews) {
        for (UIView* badgeView in tabBarButton.subviews) {
            NSString* className = NSStringFromClass([badgeView class]);

            // looking for _UIBadgeView
            if ([className rangeOfString:@"BadgeView"].location != NSNotFound) {
                for (UIView* badgeSubview in badgeView.subviews) {
                    NSString* className = NSStringFromClass([badgeSubview class]);

                    // looking for _UIBadgeBackground
                    if ([className rangeOfString:@"BadgeBackground"].location != NSNotFound) {
                        @try {
                            [badgeSubview setValue:nil forKey:@"image"];
                            [badgeSubview setBackgroundColor:[UIColor blueColor]];
                            badgeSubview.clipsToBounds = YES;
                            badgeSubview.layer.cornerRadius = badgeSubview.frame.size.height/2;
                        }
                        @catch (NSException *exception) {}
                    }

                    if ([badgeSubview isKindOfClass:[UILabel class]]) {
                        ((UILabel *)badgeSubview).textColor = [UIColor greenColor];
                    }
                }
            }
        }
    }
}

enter image description here

0