From 3db0b55fd3b0d0e6968237fdb6f29836f44710dd Mon Sep 17 00:00:00 2001 From: Anton Skopin Date: Sun, 31 Mar 2019 03:20:10 +0300 Subject: [PATCH] added badge observers --- .../Classes/CBBaseTabButton.swift | 37 +++++++++++-- .../Classes/Fade/CBFadeTabBarButton.swift | 1 + .../Classes/Flashy/CBFlashyTabBarButton.swift | 53 +++++++++++++++---- Example/ViewController.swift | 6 +++ 4 files changed, 84 insertions(+), 13 deletions(-) diff --git a/CBTabBarController/Classes/CBBaseTabButton.swift b/CBTabBarController/Classes/CBBaseTabButton.swift index cb30064..9ac469c 100644 --- a/CBTabBarController/Classes/CBBaseTabButton.swift +++ b/CBTabBarController/Classes/CBBaseTabButton.swift @@ -13,6 +13,16 @@ class CBBaseTabButton: UIButton, CBTabBarButtonProtocol { var badgeContainer = UIView() var badgeLabel = UILabel() var item: UITabBarItem? { + set { + guard let item = newValue else { return } + _item = item + } + get { + return _item + } + } + + @objc dynamic var _item: UITabBarItem = UITabBarItem() { didSet { didUpdateItem() } @@ -25,19 +35,30 @@ class CBBaseTabButton: UIButton, CBTabBarButtonProtocol { override init(frame: CGRect) { super.init(frame: frame) configure() + addObservers() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) configure() + addObservers() } required init(item: UITabBarItem) { super.init(frame: .zero) - defer { - self.item = item - } configure() + addObservers() + self.item = item + } + + deinit { + removeObserver(self, forKeyPath: #keyPath(_item.badgeValue)) + removeObserver(self, forKeyPath: #keyPath(_item.badgeColor)) + } + + func addObservers() { + addObserver(self, forKeyPath: #keyPath(_item.badgeValue), options: [.initial, .new], context: nil) + addObserver(self, forKeyPath: #keyPath(_item.badgeColor), options: [.initial, .new], context: nil) } func configure() { @@ -107,5 +128,15 @@ class CBBaseTabButton: UIButton, CBTabBarButtonProtocol { badgeContainer.backgroundColor = item?.badgeColor ?? tintColor badgeLabel.text = item?.badgeValue badgeContainer.isHidden = item?.badgeValue == nil + setNeedsLayout() + } + + override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { + switch keyPath { + case #keyPath(_item.badgeValue), #keyPath(_item.badgeColor): + didUpdateItem() + default: + break + } } } diff --git a/CBTabBarController/Classes/Fade/CBFadeTabBarButton.swift b/CBTabBarController/Classes/Fade/CBFadeTabBarButton.swift index 779e5de..fc770c7 100644 --- a/CBTabBarController/Classes/Fade/CBFadeTabBarButton.swift +++ b/CBTabBarController/Classes/Fade/CBFadeTabBarButton.swift @@ -75,5 +75,6 @@ class CBFadeTabBarButton: CBBaseTabButton { override func didUpdateItem() { super.didUpdateItem() setImage(item?.image?.withRenderingMode(.alwaysTemplate), for: .normal) + setNeedsLayout() } } diff --git a/CBTabBarController/Classes/Flashy/CBFlashyTabBarButton.swift b/CBTabBarController/Classes/Flashy/CBFlashyTabBarButton.swift index a8b4567..c5aa30a 100644 --- a/CBTabBarController/Classes/Flashy/CBFlashyTabBarButton.swift +++ b/CBTabBarController/Classes/Flashy/CBFlashyTabBarButton.swift @@ -38,29 +38,45 @@ class CBFlashyTabBarButton: CBTabBarButton { override init(frame: CGRect) { super.init(frame: frame) configureSubviews() + addObservers() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) configureSubviews() + addObservers() } required init(item: UITabBarItem) { super.init(frame: .zero) + addObservers() configureSubviews() - defer { - self.item = item - } + self.item = item } - + + deinit { + removeObserver(self, forKeyPath: #keyPath(_item.badgeValue)) + removeObserver(self, forKeyPath: #keyPath(_item.badgeColor)) + } + + private func addObservers() { + addObserver(self, forKeyPath: #keyPath(_item.badgeValue), options: [.initial, .new], context: nil) + addObserver(self, forKeyPath: #keyPath(_item.badgeColor), options: [.initial, .new], context: nil) + } + var item: UITabBarItem? { + set { + guard let item = newValue else { return } + _item = item + } + get { + return _item + } + } + + @objc dynamic var _item: UITabBarItem = UITabBarItem(){ didSet { - tabImage.image = item?.image?.withRenderingMode(.alwaysTemplate) - tabLabel.attributedText = (item as? CBExtendedTabItem)?.attributedTitle ?? attributedText(fortitle: item?.title) - badgeContainer.backgroundColor = item?.badgeColor ?? tintColor - badgeLabel.text = item?.badgeValue - badgeContainer.isHidden = item?.badgeValue == nil - setNeedsLayout() + didUpdateItem() } } @@ -175,5 +191,22 @@ class CBFlashyTabBarButton: CBTabBarButton { } } } + + private func didUpdateItem() { + tabImage.image = item?.image?.withRenderingMode(.alwaysTemplate) + tabLabel.attributedText = (item as? CBExtendedTabItem)?.attributedTitle ?? attributedText(fortitle: item?.title) + badgeContainer.backgroundColor = item?.badgeColor ?? tintColor + badgeLabel.text = item?.badgeValue + badgeContainer.isHidden = item?.badgeValue == nil + setNeedsLayout() + } + override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { + switch keyPath { + case #keyPath(_item.badgeValue), #keyPath(_item.badgeColor): + didUpdateItem() + default: + break + } + } } diff --git a/Example/ViewController.swift b/Example/ViewController.swift index a25f60e..1b4c816 100644 --- a/Example/ViewController.swift +++ b/Example/ViewController.swift @@ -40,6 +40,12 @@ class ViewController: UIViewController { let settingsVC = CBSampleViewController() settingsVC.tabBarItem = SampleTabItem(title: "Settings", image: #imageLiteral(resourceName: "Settings"), tag: 0) settingsVC.tabBarItem?.badgeColor = .red + DispatchQueue.main.asyncAfter(deadline: .now() + 2) { + settingsVC.tabBarItem?.badgeValue = "20" + } + DispatchQueue.main.asyncAfter(deadline: .now() + 3) { + settingsVC.tabBarItem?.badgeValue = "200" + } settingsVC.tabBarItem?.badgeValue = "1" settingsVC.inverseColor()