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

在Xamarin Forms iOS 13+应用程序中设置导航栏按钮上的字体,ios,xamarin.forms,Ios,Xamarin.forms,我正在尝试设置导航按钮的字体,特别是Xamarin iOS 13+应用程序中的后退按钮。我发现了这个声称有效但至少对我来说无效的东西: var style = new UINavigationBarAppearance(); var a = new UIStringAttributes(); a.Font = UIFont.SystemFontOfSize(35); a.ForegroundColor = UIColor.Yellow; style.TitleTextAttributes =

我正在尝试设置导航按钮的字体,特别是Xamarin iOS 13+应用程序中的后退按钮。我发现了这个声称有效但至少对我来说无效的东西:

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 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形式下不起作用。看起来Xamarin表单可能正在强制执行自己的标准外观,它覆盖了我在代码中输入的内容。

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

在ViewController中 如果要使其在所有控制器上工作,可以定义基本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 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();
    }
}

谢谢你的建议。我希望有一种更简单的方法,而不是手动构建新的导航栏按钮,特别是考虑到Xamarin.iOS解决方案的简单性:/
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();
    }
}