在 Xamarin Forms iOS 13+ 应用程序中设置导航栏按钮上的字体

Posted

技术标签:

【中文标题】在 Xamarin Forms iOS 13+ 应用程序中设置导航栏按钮上的字体【英文标题】:Setting the font on navigation bar buttons in a Xamarin Forms iOS 13+ app 【发布时间】:2021-03-11 17:41:08 【问题描述】:

我正在尝试在 Xamarin ios (13+) 应用程序中设置导航按钮(特别是后退按钮)的字体。我发现这个 this solution 声称可以工作但没有,至少对我来说:

var style = new UINavigationBarAppearance();

var a = new UIStringAttributes();
a.Font = UIFont.SystemFontOfSize(35);
a.ForegroundColor = UIColor.Yellow;
style.TitleTextAttributes = a;

var dic = new NSDictionary<NSString, NSObject>(
            new NSString[] a.Dictionary.Keys[0] as NSString, a.Dictionary.Keys[1] as NSString , a.Dictionary.Values
);
   
var button = new UIBarButtonItemAppearance(UIBarButtonItemStyle.Plain);
button.Normal.TitleTextAttributes = dic;
button.Highlighted.TitleTextAttributes = dic;
style.ButtonAppearance = button;

UINavigationBar.Appearance.StandardAppearance = style;

然后我将它简化了一点(看看我是否可以简单地重新着色导航栏标题)但这又什么也没做:

var style = new UINavigationBarAppearance();

var a = new UIStringAttributes()

    ForegroundColor = UIColor.Yellow
;
style.TitleTextAttributes = a;

UINavigationBar.Appearance.StandardAppearance = style;

玩得更远,我奇怪地发现,以下内容确实会重新着色导航栏标题:

var a = new UIStringAttributes()

    ForegroundColor = UIColor.Yellow
;

UINavigationBar.Appearance.TitleTextAttributes = a;

...但是使用相同的思考过程,这不会重新着色导航栏按钮:

var a = new UITextAttributes()

    TextColor = UIColor.Yellow
;

UIBarButtonItem.Appearance.SetTitleTextAttributes(a, UIControlState.Normal);

谁能明白为什么这些方法都不能用于修改导航栏按钮的样式?或者这可能是 Xamarin 的问题?

更新:我意识到第一个示例确实有效,但仅在 Xamarin iOS 中。但是,它在 Xamarin Forms 中不起作用。看起来 Xamarin Forms 可能会强制执行其自己的标准外观,这会覆盖我在代码中输入的内容。

【问题讨论】:

【参考方案1】:

在您的情况下,我们可以设置自定义 NavigationBar

在您的视图控制器中

如果你想让它在所有控制器上工作,你可以定义一个基本的 ViewController

 public override void ViewWillAppear(bool animated)
    
        base.ViewWillAppear(animated);
        var page = Element as ContentPage;
        NavigationController.NavigationBar.Hidden = true;
        double height = IsiphoneX();
        UIView backView = new UIView()
        
            BackgroundColor = UIColor.White,
            Frame = new CGRect(0,20,UIScreen.MainScreen.Bounds.Width, height),
        ;
        UIButton backBtn = new UIButton() 
            Frame = new CGRect(20, height-44, 40, 44),
            Font = UIFont.SystemFontOfSize(18),  // set style here
         ;
        backBtn.SetTitle("Back", UIControlState.Normal);
        backBtn.SetTitleColor(UIColor.Blue, UIControlState.Normal);
        backBtn.AddTarget(this,new Selector("GoBack"),UIControlEvent.TouchUpInside);
        UILabel titleLabel = new UILabel() 
            Frame=new CGRect(UIScreen.MainScreen.Bounds.Width/2-75, 0,150, height),
            Font = UIFont.SystemFontOfSize(20),
            Text = page.Title,
            TextColor = UIColor.Black,
            Lines = 0,
        ;
        UILabel line = new UILabel() 
            Frame = new CGRect(0, height, UIScreen.MainScreen.Bounds.Width, 0.5),
            BackgroundColor = UIColor.Black,
        ;

        backView.AddSubview(backBtn);
        backView.AddSubview(titleLabel);
        backView.AddSubview(line);
        View.AddSubview(backView);
    
     double IsiphoneX()
    
        double height = 44; //set height as you want here !!!
        if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
        
            if (UIApplication.SharedApplication.Delegate.GetWindow().SafeAreaInsets.Bottom > 0.0)
            
                height = 64;  //set height as you want here !!!
            
        
        return height;
    
    [Export("GoBack")]
    void GoBack()
    
        NavigationController.PopViewController(true);
    
    public override void ViewWillDisappear(bool animated)
    
        base.ViewWillDisappear(animated);

        NavigationController.NavigationBar.Hidden = false;
    

通过这种方式,您可以根据需要设置所有样式,例如 BackgroundColor 、 TextColor 甚至将后退按钮设置为图像。

【讨论】:

感谢您的建议。我希望可能有一种更简单的方法,而不是手动构建新的导航栏按钮,尤其是考虑到 Xamarin.iOS 解决方案的简单性:/【参考方案2】:

我终于找到了一种方法,可以通过覆盖 Xamarin Forms 对其自身导航栏样式的不断执行来实现:

public class MyNavigationRenderer : NavigationRenderer

    public override void ViewDidAppear(bool animated)
    
        base.ViewDidAppear(animated);

        UpdateStyle();

        Element.PropertyChanged += HandlePropertyChanged;
    

    void UpdateStyle()
    
        var navigationBarAppearance = NavigationBar.StandardAppearance;
        var titleTextAttributes = new UIStringAttributes
        
            ForegroundColor = UIColor.Yellow,
            Font = UIFont.SystemFontOfSize(35)
        ;

        var dic = new NSDictionary<NSString, NSObject>(
            new NSString[]  titleTextAttributes.Dictionary.Keys[0] as NSString, titleTextAttributes.Dictionary.Keys[1] as NSString , titleTextAttributes.Dictionary.Values
        );

        var button = new UIBarButtonItemAppearance(UIBarButtonItemStyle.Plain);
        button.Normal.TitleTextAttributes = dic;
        button.Highlighted.TitleTextAttributes = dic;

        navigationBarAppearance.ButtonAppearance = button;

        NavigationBar.StandardAppearance = navigationBarAppearance;
        NavigationBar.CompactAppearance = navigationBarAppearance;
        NavigationBar.ScrollEdgeAppearance = navigationBarAppearance;
    

    void HandlePropertyChanged(object sender, PropertyChangedEventArgs e)
    
        UpdateStyle();
    

【讨论】:

这主要对我有用。不得不在 ViewWillAppear 和 ViewDidLayoutSubviews 中进行一些 UpdateStyle() 调用

以上是关于在 Xamarin Forms iOS 13+ 应用程序中设置导航栏按钮上的字体的主要内容,如果未能解决你的问题,请参考以下文章

让你的Xamarin.Forms应用程序访问

MvvmCross 与 Xamarin.Forms 和自定义 iOS 渲染器 - 防止导航滑动 iOS - MasterDetail

Xamarin简介

无法在 UWP 中设置 SQLite 对象 - Xamarin Forms

Xamarin.forms(或)xamarin.ios/xamarin.android(或)本机

Xamarin Forms - 每 10 秒获取一次设备位置(当应用程序在前台/后台运行时)