Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS Change badge color inside UIMoreNavigationController in UITabBarController

I customize the background color and its tint color with this code:

var blackBGColor = new UIColor(new nfloat(40) / 255f,
                               new nfloat(40) / 255f,
                               new nfloat(40) / 255f, 1f);

this.MoreNavigationController.TopViewController.View.BackgroundColor = blackBGColor;

var moreTableView = (UITableView)this.MoreNavigationController.TopViewController.View;
moreTableView.TintColor = UIColor.White;
foreach (var cell in moreTableView.VisibleCells)
{
     cell.BackgroundColor = blackBGColor;
     cell.TextLabel.TextColor = UIColor.White;
     var selectedView = new UIView
     {
          BackgroundColor = UIColor.DarkGray
     };
     cell.SelectedBackgroundView = selectedView;
}

this.MoreNavigationController.NavigationBar.BarStyle = UIBarStyle.Black;
this.MoreNavigationController.NavigationBar.Translucent = false;
this.MoreNavigationController.NavigationBar.TintColor = UIColor.White;
this.MoreNavigationController.NavigationBar.BarTintColor = new UIColor(24f / 255f, 24f / 255f, 24f / 255f, 1f);

But I couldn't change the badge color inside UIMoreNavigationController.

I've tried this:

this.MoreNavigationController.TopViewController.TabBarItem.BadgeColor = UIColor.White 

but it's not working.

Tried this one too inside WillShowViewController:

this.ViewControllers[4].TabBarItem.BadgeColor = UIColor.White

but still not working.

Is there any way to change the badge color?

More navigation controller


UPDATE:

After investigating the hierarchy of MoreNavigationController, apparently the badge value for Priority and DueBy tab is assign to a UILabel inside _UITableViewCellBadgeNeue. The hierarchy is:

  • this.MoreNavigationController.ViewControllers[0]: this is a UIMoreListController
    • Get the View and cast it to UITableView because that View is a _UIMoreListTableView
      • Then iterate inside that tableview VisibleCells, check the IEnumerator and in the forth object there is _UITableViewCellBadgeNeue
        • The SubViews[0] inside _UITableViewCellBadgeNeue is a UILabel and the label's text is the badge value.

Based on that, I change the label TextColor and BackgroundColor in WillShowViewController. It works but I need to go back and forth from Priority/DueBy tab to More tab. It never works on the first time.

[Export("navigationController:willShowViewController:animated:")]
public void WillShowViewController(UINavigationController navigationController, UIViewController viewController, bool animated)
{
     if (this.MoreNavigationController.ViewControllers.Contains(viewController))
     {
          this.ViewControllers[4].TabBarItem.BadgeValue = this.ViewModel.SelectedPrioritiesFilter.Count > 0 ? this.ViewModel.SelectedPrioritiesFilter.Count.ToString() : null;
          this.ViewControllers[5].TabBarItem.BadgeValue = this.ViewModel.SelectedDueByFilter != null ? "1" : null;

          //this is the code to change the color
          var vc = this.MoreNavigationController.ViewControllers[0];
          var moreTableView = (UITableView)vc.View;
          foreach (var cell in moreTableView.VisibleCells)
          {
               var enumerator = cell.GetEnumerator();
               var i = 0;
               while (enumerator.MoveNext())
               {
                    //_UITableViewCellBadgeNeue is in the forth object
                    if(i == 3) 
                    {
                        //_UITableViewCellBadgeNeue is a UIView
                        if (enumerator.Current is UIView)
                        {
                             var current = (UIView)enumerator.Current;
                             if (current != null)
                             {
                                 if (current.Subviews.Length > 0)
                                 {
                                      var label = (UILabel)current.Subviews[0];
                                      label.TextColor = UIColor.White;
                                      label.BackgroundColor = UIColor.Clear;
                                 }
                             }
                        }
                    }
                    i++;
               }
          }
     }
}
like image 938
currarpickt Avatar asked Nov 07 '22 08:11

currarpickt


1 Answers

I reproduced your issue and figured the reason out.

It is because the TableView has not finished rendering(drawing) when you retrieve the view hierarchy in WillShowViewController.

My test

View Hierarchy in WillShowViewController

UITableViewCellContentView
UIButton 

View Hierarchy in DidShowViewController

UITableViewCellContentView
UIButton
_UITableViewCellBadgeNeue
_UITableViewCellSeparatorView
UITableViewCellContentView
UIButton
_UITableViewCellSeparatorView

So you just need replace the WillShowViewController with DidShowViewController.

PS: Small Suggestion

To avoid the change of View Hierarchy by Apple, you can use the condition like if (view.Class.Name.ToString() == "_UITableViewCellBadgeNeue") instead of judging which level the _UITableViewCellBadgeNeue is.

like image 194
ColeX - MSFT Avatar answered Nov 15 '22 00:11

ColeX - MSFT