Как изменить цвета TabBar и NavigationBar в форматах Xamarin?

У меня есть приложение Xamarin Forms, и в настоящее время я работаю над кодом для iOS. В моих настройках у меня есть возможность изменить тему приложения (Темный и Светлый). Это в основном просто меняет цвета фона и цвета текста на страницах. Теперь я хочу изменить SelectedImageTintColor и BarTintColor для TabBar, а также BarTintColor и TintColor для NavigationBar. В настоящий момент я создаю средство визуализации для страницы с вкладками:

protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
   base.OnElementChanged(e);
   App.theme = (Theme)App.DB.GetIntSetting("ThemeColor");
   switch (App.theme)
   {
      case Theme.Dark:
      {
         TabBar.SelectedImageTintColor = UIColor.FromRGB(255, 165, 0);
         TabBar.BarTintColor = UIColor.Black;
         break;
      }
      case Theme.Light:
      {
         TabBar.SelectedImageTintColor = UIColor.FromRGB(60, 132, 60);
         TabBar.BarTintColor = UIColor.White;
         break;
      }
   }
}

Прямо сейчас эти цвета вступают в силу только при первом запуске приложения.

введите описание изображения здесь

Я исследовал эту проблему, но не смог найти ответа от кого-либо о том, как решить эту проблему.

Я знаю, что было много изменений в Xamarin, поэтому я хотел бы узнать, есть ли какие-либо недавние разработки или новые способы решения этой проблемы. Я открыт для изучения любых возможных предложений, поскольку часть требования к приложению заключается в том, чтобы иметь возможность изменять эти цвета.

Редактирование:

Моя страница Tabbed была создана следующим образом:

public partial class MainPage : TabbedPage
{
   public MainPage()
   {
      InitializeComponent();
      var phrasesPage = new NavigationPage(new PhrasesPage())
      {
         Title = "Play",
         Icon = "play1.png"
      };
      var settingsPage = new NavigationPage(new SettingsPage())
      {
         Title = "Settings",
         Icon = "settings.png"
      };
      // other declarations here

      Children.Add(phrasesPage);
      Children.Add(settingsPage);
      // and more
   }
}

Например, если я выбираю тему Dark, тогда цвет фона TabBar и NavigationBar будет черным, то элемент TabBar selected будет оранжевым, а текст NavigationBar будет белым. Аналогично, если я выбираю тему "Свет", то цвет фона TabBar и NavigationBar будет белым, то элемент TabBar selected будет зеленым, а текст NavigationBar будет черным.

Ответ 1

Я думаю, проблема в том, что вы не слушаете и не изменяете тему изменения темы. Вы устанавливаете цвета в OnElementChanged, который не будет вызываться снова при изменении темы.

Вы можете создать свойство, которое запустит событие, которое вы подписываете в своем настраиваемом рендерере. Например, если вы создаете свойство в своем классе App, то в своем пользовательском средстве отображения вкладки TabbedPage вы можете сделать:

protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
    base.OnElementChanged(e);

    if(e.OldElement != null)
    {
        App.Current.PropertyChanged -= Current_PropertyChanged;
        return;
    }

    App.Current.PropertyChanged += Current_PropertyChanged; //subscribe to the App class' built in property changed event
    UpdateTheme();
}

void Current_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
    if(e.PropertyName == "DarkTheme")
    {
        UpdateTheme();
    }
}

Так как панель навигации управляется NavigationPage, вам также придется прислушиваться к изменению свойства. К счастью, вам не понадобится настраиваемый рендерер, так как вы можете изменить цвет бара и текста с помощью свойств Forms. Таким образом, вы можете создать класс, который наследует от NavigationPage и подписаться на событие:

public class CustomNavigationPage : NavigationPage
{
    public CustomNavigationPage(Page root) : base(root)
    {
        if(Device.OS == TargetPlatform.iOS)
        {
            App.Current.PropertyChanged += Current_PropertyChanged;
        }
    }
}

Я создал образец проекта, который демонстрирует все это, чтобы вы могли проверить его.

Ответ 2

Вы можете использовать свойство tabbar для изменения фона и цвета значка, когда вам нужно использовать.

 TabBar.TintColor = UIColor.White; // changer as per your need for tab icon color
TabBar.BarTintColor = UIColor.Black; // changer as per your need for tabbar backgroungcolor 

то же, что и для навигации

this.NavigationController.NavigationBar.TintColor = UIColor.White;//change as per your need for tab icon color

this.NavigationController.NavigationBar.BarTintColor = UIColor.Black;// changer as per your need for Navbar' backgroungcolor 

Ответ 3

Знаете ли вы о функции "Динамический ресурс" в форматах Xamarin?

Я дам свой способ сделать это. Может быть, нелегко, но я думаю, что он может работать.

Шаг 1: В наборах клавиш app.xaml и значках по умолчанию ниже

<FileImageSource x:Key="PlayIconKey">playdark.png</FileImageSource>
<FileImageSource x:Key="AboutIconKey">aboutdark.png</FileImageSource>

and

<Image Source="{ DynamicResource PlayIconKey }" />
<Image Source="{ DynamicResource AboutIconKey}" />

и т.д..

Шаг 2: На вкладке, указанной как

var phrasesPage = new NavigationPage(new PhrasesPage())
{
 Title = "Play",
 Icon = Application.Current.Resources["PlayIconKey"]
};

и т.д. для других страниц в TabbedPage

Шаг 3: Теперь, когда вы меняете настройки, просто установите

Application.Current.Resources["PlayIconKey"] = "playlight.png" 

и другие значки.

При таком подходе вы можете изменить все значки в одном месте. Дайте мне знать ваше мнение об этом.