Xamarin.ios 的 CustomTabRenderer
CustomTabRenderer for Xamarin.ios
我已经使用 Xamarin 几个月了,但仍然 运行 时不时遇到一些麻烦。我正在使用自定义渲染器来更改选项卡的外观。在不同的选项卡之间切换时,它工作得很好。但是,当我使用以下方式导航到我的 tabbedPage 时:
Children.Add(new UnitMapPage { Title = "Map", Icon = "map.png" });
CurrentPage = mapPage;
页面在正确的选项卡上打开,但 TabbarItem 的文本看起来与未选中的项目完全一样。只要您点击任何选项卡,它就会更改为正确的样式。这是我的自定义渲染器。
class CustomTabRenderer : TabbedRenderer
{
private UnitViewModel _unitViewModel;
private TabbedPage _unitPage;
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (e.NewElement != null) {
var unitPage = (TabbedPage)e.NewElement;
_unitPage = unitPage;
_unitViewModel = (UnitViewModel)_unitPage.BindingContext;
_unitViewModel.PropertyChanged += OnElementPropertyChanged;
}
// Set Text Font for unselected tab states
UITextAttributes normalTextAttributes = new UITextAttributes();
normalTextAttributes.Font = UIFont.SystemFontOfSize(10.0F, UIFontWeight.Regular); // unselected
normalTextAttributes.TextColor = UIColor.White;
UITabBarItem.Appearance.SetTitleTextAttributes(normalTextAttributes, UIControlState.Normal);
}
void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "AlertCount")
{
if (TabBar.Items != null)
{
foreach (var item in TabBar.Items)
{
item.Image = item.Image.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
if (item.Title == "History" && _unitViewModel != null)
{
if (_unitViewModel.AlertCount > 0)
item.BadgeValue = _unitViewModel.AlertCount.ToString();
else
item.BadgeValue = null;
}
}
}
}
}
public override void ViewWillAppear(bool animated)
{
if (TabBar.Items != null)
{
foreach (var item in TabBar.Items)
{
item.Image = item.Image.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
if (item.Title == "History" && _unitViewModel != null)
{
if (_unitViewModel.AlertCount > 0)
item.BadgeValue = _unitViewModel.AlertCount.ToString();
else
item.BadgeValue = null;
}
}
}
base.ViewWillAppear(animated);
}
public override UIViewController SelectedViewController
{
get
{
UITextAttributes selectedTextAttributes = new UITextAttributes();
selectedTextAttributes.Font = UIFont.SystemFontOfSize(12.0F, UIFontWeight.Heavy); // SELECTED
if (base.SelectedViewController != null)
{
base.SelectedViewController.TabBarItem.SetTitleTextAttributes(selectedTextAttributes, UIControlState.Normal);
}
return base.SelectedViewController;
}
set
{
base.SelectedViewController = value;
foreach (UIViewController viewController in base.ViewControllers)
{
UITextAttributes normalTextAttributes = new UITextAttributes();
normalTextAttributes.Font = UIFont.SystemFontOfSize(10.0F, UIFontWeight.Regular); // unselected
normalTextAttributes.TextColor = UIColor.White;
viewController.TabBarItem.SetTitleTextAttributes(normalTextAttributes, UIControlState.Normal);
}
}
}
}
我相信你只需要交换:
CurrentPage = yourPage;
和
SelectedItem = yourPage;
当我将正在测试的设备从 ios9 升级到 ios10 时,问题似乎已经出现(无法确认这一点,因为我无法找到 ios9 我可以测试的设备)。
通读关于这个 post 的答案:How do I override the Xamarin Forms TabbedPage item fonts for iOS?,让我自己尝试了各种东西 ViewWillAppear。
通过更改我的代码以在 ViewWillAppear 中设置 selectedTextAttributes 解决了这个问题。不确定这是否是最好的方法,但它成功了!
public override void ViewWillAppear(bool animated)
{
if (TabBar.Items != null)
{
foreach (var item in TabBar.Items)
{
item.Image = item.Image.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
if (item.Title == "History" && _unitViewModel != null)
{
if (_unitViewModel.AlertCount > 0)
item.BadgeValue = _unitViewModel.AlertCount.ToString();
else
item.BadgeValue = null;
}
if (item.Title.Equals(_unitPage.CurrentPage.Title))
{
UITextAttributes selectedTextAttributes = new UITextAttributes();
selectedTextAttributes.Font = UIFont.SystemFontOfSize(12.0F, UIFontWeight.Heavy); // SELECTED
if (base.SelectedViewController != null)
{
base.SelectedViewController.TabBarItem.SetTitleTextAttributes(selectedTextAttributes, UIControlState.Normal);
}
}
}
}
base.ViewWillAppear(animated);
}
我已经使用 Xamarin 几个月了,但仍然 运行 时不时遇到一些麻烦。我正在使用自定义渲染器来更改选项卡的外观。在不同的选项卡之间切换时,它工作得很好。但是,当我使用以下方式导航到我的 tabbedPage 时:
Children.Add(new UnitMapPage { Title = "Map", Icon = "map.png" });
CurrentPage = mapPage;
页面在正确的选项卡上打开,但 TabbarItem 的文本看起来与未选中的项目完全一样。只要您点击任何选项卡,它就会更改为正确的样式。这是我的自定义渲染器。
class CustomTabRenderer : TabbedRenderer
{
private UnitViewModel _unitViewModel;
private TabbedPage _unitPage;
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (e.NewElement != null) {
var unitPage = (TabbedPage)e.NewElement;
_unitPage = unitPage;
_unitViewModel = (UnitViewModel)_unitPage.BindingContext;
_unitViewModel.PropertyChanged += OnElementPropertyChanged;
}
// Set Text Font for unselected tab states
UITextAttributes normalTextAttributes = new UITextAttributes();
normalTextAttributes.Font = UIFont.SystemFontOfSize(10.0F, UIFontWeight.Regular); // unselected
normalTextAttributes.TextColor = UIColor.White;
UITabBarItem.Appearance.SetTitleTextAttributes(normalTextAttributes, UIControlState.Normal);
}
void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "AlertCount")
{
if (TabBar.Items != null)
{
foreach (var item in TabBar.Items)
{
item.Image = item.Image.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
if (item.Title == "History" && _unitViewModel != null)
{
if (_unitViewModel.AlertCount > 0)
item.BadgeValue = _unitViewModel.AlertCount.ToString();
else
item.BadgeValue = null;
}
}
}
}
}
public override void ViewWillAppear(bool animated)
{
if (TabBar.Items != null)
{
foreach (var item in TabBar.Items)
{
item.Image = item.Image.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
if (item.Title == "History" && _unitViewModel != null)
{
if (_unitViewModel.AlertCount > 0)
item.BadgeValue = _unitViewModel.AlertCount.ToString();
else
item.BadgeValue = null;
}
}
}
base.ViewWillAppear(animated);
}
public override UIViewController SelectedViewController
{
get
{
UITextAttributes selectedTextAttributes = new UITextAttributes();
selectedTextAttributes.Font = UIFont.SystemFontOfSize(12.0F, UIFontWeight.Heavy); // SELECTED
if (base.SelectedViewController != null)
{
base.SelectedViewController.TabBarItem.SetTitleTextAttributes(selectedTextAttributes, UIControlState.Normal);
}
return base.SelectedViewController;
}
set
{
base.SelectedViewController = value;
foreach (UIViewController viewController in base.ViewControllers)
{
UITextAttributes normalTextAttributes = new UITextAttributes();
normalTextAttributes.Font = UIFont.SystemFontOfSize(10.0F, UIFontWeight.Regular); // unselected
normalTextAttributes.TextColor = UIColor.White;
viewController.TabBarItem.SetTitleTextAttributes(normalTextAttributes, UIControlState.Normal);
}
}
}
}
我相信你只需要交换:
CurrentPage = yourPage;
和
SelectedItem = yourPage;
当我将正在测试的设备从 ios9 升级到 ios10 时,问题似乎已经出现(无法确认这一点,因为我无法找到 ios9 我可以测试的设备)。
通读关于这个 post 的答案:How do I override the Xamarin Forms TabbedPage item fonts for iOS?,让我自己尝试了各种东西 ViewWillAppear。
通过更改我的代码以在 ViewWillAppear 中设置 selectedTextAttributes 解决了这个问题。不确定这是否是最好的方法,但它成功了!
public override void ViewWillAppear(bool animated)
{
if (TabBar.Items != null)
{
foreach (var item in TabBar.Items)
{
item.Image = item.Image.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
if (item.Title == "History" && _unitViewModel != null)
{
if (_unitViewModel.AlertCount > 0)
item.BadgeValue = _unitViewModel.AlertCount.ToString();
else
item.BadgeValue = null;
}
if (item.Title.Equals(_unitPage.CurrentPage.Title))
{
UITextAttributes selectedTextAttributes = new UITextAttributes();
selectedTextAttributes.Font = UIFont.SystemFontOfSize(12.0F, UIFontWeight.Heavy); // SELECTED
if (base.SelectedViewController != null)
{
base.SelectedViewController.TabBarItem.SetTitleTextAttributes(selectedTextAttributes, UIControlState.Normal);
}
}
}
}
base.ViewWillAppear(animated);
}