10

以下の質問は私のものと似ています。

カスタム UIImage を UITabBarItem バッジとして使用するには?

自分で描く代わりに背景画像を使用することはできますか? 私のアプリは 1 桁の BadgeValue しか使用しないので、問題ないと思います。

どうしてもできない場合は、代わりにバッジの色を変更できるかどうか知りたいです。以下の質問の答えは、実際には役に立ちません。

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

4

6 に答える 6

13

これが最善の策です。この拡張子をファイル スコープに追加すると、バッジを好きなようにカスタマイズできます。self.tabBarController!.setBadges([1,0,2])ルート ビュー コントローラーのいずれかを呼び出すだけです。

明確にするために、これは 3 つの項目を持つタブ バーで、バッジの値は左から右に移動します。

代わりに画像を追加したい場合は、addBadgeメソッドを変更するだけです

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

        var labelExistsForIndex = [Bool]()

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

        for view in self.tabBar.subviews where view is 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 i in 0...(labelExistsForIndex.count - 1) where !labelExistsForIndex[i] && (badgeValues[i] > 0) {
            addBadge(index: i, value: badgeValues[i], color: .red, 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 = 5
        let yOffset: CGFloat = -12

        let badgeView = PGTabBadge()
        badgeView.frame.size =  CGSize(width: 12, height: 12)
        badgeView.center = CGPoint(x: (itemWidth * itemPosition) - (itemWidth / 2) + xOffset, y: 20 + yOffset)
        badgeView.layer.cornerRadius = badgeView.bounds.width/2
        badgeView.clipsToBounds = true
        badgeView.textColor = UIColor.white
        badgeView.textAlignment = .center
        badgeView.font = font
        badgeView.text = String(value)
        badgeView.backgroundColor = bgColor
        badgeView.tag = index
        tabBar.addSubview(badgeView)

    }
}
    
class PGTabBadge: UILabel { }
于 2015-08-30T12:39:09.547 に答える
3

TimWhiting's answerに基づく別のソリューションを次に示します。

extension UITabBar {
        func setBadge(value: String?, at index: Int, withConfiguration configuration: TabBarBadgeConfiguration = TabBarBadgeConfiguration()) {
            let existingBadge = subviews.first { ($0 as? TabBarBadge)?.hasIdentifier(for: index) == true }
            existingBadge?.removeFromSuperview()

            guard let tabBarItems = items,
                let value = value else { return }

            let itemPosition = CGFloat(index + 1)
            let itemWidth = frame.width / CGFloat(tabBarItems.count)
            let itemHeight = frame.height

            let badge = TabBarBadge(for: index)
            badge.frame.size = configuration.size
            badge.center = CGPoint(x: (itemWidth * itemPosition) - (0.5 * itemWidth) + configuration.centerOffset.x,
                                   y: (0.5 * itemHeight) + configuration.centerOffset.y)
            badge.layer.cornerRadius = 0.5 * configuration.size.height
            badge.clipsToBounds = true
            badge.textAlignment = .center
            badge.backgroundColor = configuration.backgroundColor
            badge.font = configuration.font
            badge.textColor = configuration.textColor
            badge.text = value

            addSubview(badge)
        }
    }

    class TabBarBadge: UILabel {
        var identifier: String = String(describing: TabBarBadge.self)

        private func identifier(for index: Int) -> String {
            return "\(String(describing: TabBarBadge.self))-\(index)"
        }

        convenience init(for index: Int) {
            self.init()
            identifier = identifier(for: index)
        }

        func hasIdentifier(for index: Int) -> Bool {
            let has = identifier == identifier(for: index)
            return has
        }
    }

    class TabBarBadgeConfiguration {
        var backgroundColor: UIColor = .red
        var centerOffset: CGPoint = .init(x: 12, y: -9)
        var size: CGSize = .init(width: 17, height: 17)
        var textColor: UIColor = .white
        var font: UIFont! = .systemFont(ofSize: 11) {
            didSet { font = font ?? .systemFont(ofSize: 11) }
        }

        static func construct(_ block: (TabBarBadgeConfiguration) -> Void) -> TabBarBadgeConfiguration {
            let new = TabBarBadgeConfiguration()
            block(new)
            return new
        }
    }
于 2019-03-06T06:41:57.957 に答える
1

うーん...組み込みのバッジの背景を変更することは、私には不可能に思えます。しかし、代わりに可能なことは次のとおりです。

TabBarController をサブクラス化し、NIB にレイアウトされたカスタム ビューを構築し、それをタブ バー内の必要な場所にあるビュー階層に追加します。

カスタム ビューでは、画像を背景として設定し、その背景の上にラベルを設定して、数値を表示し、コードで変更することができます。

次に、ビューをタブ バーの内側に配置するカスタム ビューの水平方向および垂直方向の位置を把握する必要があります。

これが少し役立つことを願っています。セバスチャン

于 2013-04-29T08:38:26.490 に答える
1

TimWhiting の回答が Swift 4 に更新され、一部の力のアンラップが削除されました。

extension UITabBarController {
  func setBadges(badgeValues: [Int]) {
    var labelExistsForIndex = [Bool]()

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

    for view in tabBar.subviews {
      if let badgeView = view as? PGTabBadge {
        let index = badgeView.tag

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

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

    for i in 0 ... labelExistsForIndex.count - 1 where !labelExistsForIndex[i] && badgeValues[i] > 0 {
      addBadge(
        index: 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) {
    guard let tabBarItems = tabBar.items else { return }
    let itemPosition = CGFloat(index + 1)
    let itemWidth: CGFloat = tabBar.frame.width / CGFloat(tabBarItems.count)

    let bgColor = color

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

    let badgeView = PGTabBadge()
    badgeView.frame.size = CGSize(width: 17, height: 17)
    badgeView.center = CGPoint(x: (itemWidth * itemPosition) - (itemWidth / 2) + xOffset, y: 20 + yOffset)
    badgeView.layer.cornerRadius = badgeView.bounds.width / 2
    badgeView.clipsToBounds = true
    badgeView.textColor = UIColor.white
    badgeView.textAlignment = .center
    badgeView.font = font
    badgeView.text = String(value)
    badgeView.backgroundColor = bgColor
    badgeView.tag = index
    tabBar.addSubview(badgeView)
  }
}

class PGTabBadge: UILabel {}

サンプル画像

ここに画像の説明を入力

于 2019-01-07T20:02:18.993 に答える