C# 如何将FreshTabbedNavigationContainer选项卡式页面更改为顶部,并在xamarin表单中更改ios的图标和字体大小

C# 如何将FreshTabbedNavigationContainer选项卡式页面更改为顶部,并在xamarin表单中更改ios的图标和字体大小,c#,ios,xamarin.forms,tabbedpage,freshmvvm,C#,Ios,Xamarin.forms,Tabbedpage,Freshmvvm,我已将freshmvvm用于我的xamarin表单应用程序。FreshTabbedNavigationContainer选项卡式页面在android上运行良好。我已经定制了android标签页的字体大小、字体颜色、图像大小。但在IOS中,我不知道如何像android一样从下到上改变标签栏,也不知道如何改变图标和字体的大小。请任何人建议我这样做。我的标签页代码如下所示 var tabbedPage = new FreshTabbedNavigationContainer();

我已将freshmvvm用于我的xamarin表单应用程序。FreshTabbedNavigationContainer选项卡式页面在android上运行良好。我已经定制了android标签页的字体大小、字体颜色、图像大小。但在IOS中,我不知道如何像android一样从下到上改变标签栏,也不知道如何改变图标和字体的大小。请任何人建议我这样做。我的标签页代码如下所示

var tabbedPage = new FreshTabbedNavigationContainer();            
tabbedPage.AddTab<FirstPageModel>("One", "icon.png");
tabbedPage.AddTab<SecondPageModel>("Two", "icon.png");
await Application.Current.MainPage.Navigation.PushAsync(tabbedPage);
NavigationPage.SetHasNavigationBar(tabbedPage, false);
如何将选项卡栏更改为ios可滚动。在我的选项卡式页面中,文本和图标之间的空间为零。请参考截图

GitHub使用自定义版本的Xamarin Forms TabbedPage实现了类似的功能,但是由于
FreshTabbedNavigationContainer
继承了同一个(TabbedPage)功能,您可以直接使用它,它应该可以像一个符咒一样工作

public class TopTabbedPage : FreshTabbedNavigationContainer
{
    public TopTabbedPage()
    {
        //BarBackgroundColor = Color.Blue;
        //BarTextColor = Color.White;
    }

    public static readonly BindableProperty BarIndicatorColorProperty = BindableProperty.Create(
        nameof(BarIndicatorColor),
        typeof(Color),
        typeof(TopTabbedPage),
        Color.White,
        BindingMode.OneWay);
    public Color BarIndicatorColor
    {
        get { return (Color)GetValue(BarIndicatorColorProperty); }
        set { SetValue(BarIndicatorColorProperty, value); }
    }


    public static readonly BindableProperty SwipeEnabledColorProperty = BindableProperty.Create(
        nameof(SwipeEnabled),
        typeof(bool),
        typeof(TopTabbedPage),
        true,
        BindingMode.OneWay);
    public bool SwipeEnabled
    {
        get { return (bool)GetValue(SwipeEnabledColorProperty); }
        set { SetValue(SwipeEnabledColorProperty, value); }
    }
}
然后渲染器将如下所示:

[assembly: ExportRenderer(typeof(TopTabbedPage), typeof(TopTabbedRenderer))]

namespace Naxam.Controls.Platform.iOS
{
using Platform = Xamarin.Forms.Platform.iOS.Platform;
using Forms = Xamarin.Forms.Forms;

public partial class TopTabbedRenderer :
    UIViewController
{
    public static void Init()
    {
    }

    UIColor _defaultBarColor;
    bool _defaultBarColorSet;
    bool _loaded;
    Size _queuedSize;
    int lastSelectedIndex;

    Page Page => Element as Page;

    UIPageViewController pageViewController;

    protected UIViewController SelectedViewController;
    protected IList<UIViewController> ViewControllers;

    protected IPageController PageController
    {
        get { return Page; }
    }

    protected TopTabbedPage Tabbed
    {
        get { return (TopTabbedPage)Element; }
    }

    protected TabsView TabBar;
    private NSLayoutConstraint tabBarHeight;

    public TopTabbedRenderer()
    {
        ViewControllers = new UIViewController[0];

        pageViewController = new UIPageViewController(
            UIPageViewControllerTransitionStyle.Scroll,
            UIPageViewControllerNavigationOrientation.Horizontal,
            UIPageViewControllerSpineLocation.None
        );

        TabBar = new TabsView
        {
            TranslatesAutoresizingMaskIntoConstraints = false
        };
        TabBar.TabsSelectionChanged += HandleTabsSelectionChanged;
    }

    public override void DidRotate(UIInterfaceOrientation fromInterfaceOrientation)
    {
        base.DidRotate(fromInterfaceOrientation);

        View.SetNeedsLayout();
    }

    public override void ViewDidAppear(bool animated)
    {
        PageController.SendAppearing();
        base.ViewDidAppear(animated);
    }

    public override void ViewDidDisappear(bool animated)
    {
        base.ViewDidDisappear(animated);
        PageController.SendDisappearing();
    }

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        View.AddSubview(TabBar);

        AddChildViewController(pageViewController);
        View.AddSubview(pageViewController.View);
        pageViewController.View.TranslatesAutoresizingMaskIntoConstraints = false;
        pageViewController.DidMoveToParentViewController(this);


        var views = NSDictionary.FromObjectsAndKeys(
            new NSObject[] {
            TabBar,
            pageViewController.View
        },
            new NSObject[] {
            (NSString) "tabbar",
            (NSString) "content"
        }
        );

        View.AddConstraints(NSLayoutConstraint.FromVisualFormat("V:|-0-[tabbar]-0-[content]-0-|",
                                                                0,
                                                                null,
                                                                views));
        View.AddConstraints(NSLayoutConstraint.FromVisualFormat("H:|-0-[tabbar]-0-|",
                                                                0,
                                                                null,
                                                                views));
        View.AddConstraints(NSLayoutConstraint.FromVisualFormat("H:|-0-[content]-0-|",
                                                                0,
                                                                null,
                                                                views));


        tabBarHeight = NSLayoutConstraint.Create(
            TabBar,
            NSLayoutAttribute.Height,
            NSLayoutRelation.Equal,
            1, 68
        );
        TabBar.AddConstraint(tabBarHeight);

        if (pageViewController.ViewControllers.Length == 0
            && lastSelectedIndex >= 0 || lastSelectedIndex < ViewControllers.Count)
        {
            pageViewController.SetViewControllers(
                new[] { ViewControllers[lastSelectedIndex] },
               UIPageViewControllerNavigationDirection.Forward,
               true, null
            );
        }

        UpdateSwipe(Tabbed.SwipeEnabled);
        pageViewController.DidFinishAnimating += HandlePageViewControllerDidFinishAnimating;
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            PageController?.SendDisappearing();

            if (Tabbed != null)
            {
                Tabbed.PropertyChanged -= OnPropertyChanged;
                Tabbed.PagesChanged -= OnPagesChanged;
                TabBar.TabsSelectionChanged -= HandleTabsSelectionChanged;
            }

            if (pageViewController != null)
            {
                pageViewController.WeakDataSource = null;
                pageViewController.DidFinishAnimating -= HandlePageViewControllerDidFinishAnimating;
                pageViewController?.Dispose();
            }
        }

        base.Dispose(disposing);
    }

    protected virtual void OnElementChanged(VisualElementChangedEventArgs e)
    {
        ElementChanged?.Invoke(this, e);
    }

    UIViewController GetViewController(Page page)
    {
        var renderer = Platform.GetRenderer(page);
        return renderer?.ViewController;
    }

    void OnPagePropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName != Page.TitleProperty.PropertyName)
            return;

        if (!(sender is Page page) || page.Title is null)
            return;

        TabBar.ReplaceItem(page.Title, Tabbed.Children.IndexOf(page));
    }

    void OnPagesChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        e.Apply((o, i, c) => SetupPage((Page)o, i), (o, i) => TeardownPage((Page)o, i), Reset);

        SetControllers();

        UIViewController controller = null;
        if (Tabbed.CurrentPage != null)
        {
            controller = GetViewController(Tabbed.CurrentPage);
        }

        if (controller != null && controller != SelectedViewController)
        {
            SelectedViewController = controller;
            var index = ViewControllers.IndexOf(SelectedViewController);
            MoveToByIndex(index);
            TabBar.SelectedIndex = index;
        }
    }

    void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == nameof(TabbedPage.CurrentPage))
        {
            var current = Tabbed.CurrentPage;
            if (current == null)
                return;

            var controller = GetViewController(current);
            if (controller == null)
                return;

            SelectedViewController = controller;
            var index = ViewControllers.IndexOf(SelectedViewController);
            MoveToByIndex(index);
            TabBar.SelectedIndex = index;
        }
        else if (e.PropertyName == TabbedPage.BarBackgroundColorProperty.PropertyName)
        {
            UpdateBarBackgroundColor();
        }
        else if (e.PropertyName == TabbedPage.BarTextColorProperty.PropertyName)
        {
            UpdateBarTextColor();
        }
        else if (e.PropertyName == TopTabbedPage.BarIndicatorColorProperty.PropertyName)
        {
            UpdateBarIndicatorColor();
        }
        else if (e.PropertyName == TopTabbedPage.SwipeEnabledColorProperty.PropertyName)
        {
            UpdateSwipe(Tabbed.SwipeEnabled);
        }
    }

    public override UIViewController ChildViewControllerForStatusBarHidden()
    {
        var current = Tabbed.CurrentPage;
        if (current == null)
            return null;

        return GetViewController(current);
    }

    void UpdateSwipe(bool swipeEnabled)
    {
        pageViewController.WeakDataSource = swipeEnabled ? this : null;
    }

    void Reset()
    {
        var i = 0;
        foreach (var page in Tabbed.Children)
        {
            SetupPage(page, i++);
        }
    }

    void SetControllers()
    {
        var list = new List<UIViewController>();
        var titles = new List<string>();
        for (var i = 0; i < Tabbed.Children.Count; i++)
        {
            var child = Tabbed.Children[i];
            var v = child as VisualElement;
            if (v == null)
                continue;

            var renderer = Platform.GetRenderer(v);
            if (renderer == null) continue;

            list.Add(renderer.ViewController);

            titles.Add(Tabbed.Children[i].Title);
        }
        ViewControllers = list.ToArray();
        TabBar.SetItems(titles);
    }

    void SetupPage(Page page, int index)
    {
        IVisualElementRenderer renderer = Platform.GetRenderer(page);
        if (renderer == null)
        {
            renderer = Platform.CreateRenderer(page);
            Platform.SetRenderer(page, renderer);
        }

        page.PropertyChanged -= OnPagePropertyChanged;
        page.PropertyChanged += OnPagePropertyChanged;
    }

    void TeardownPage(Page page, int index)
    {
        page.PropertyChanged -= OnPagePropertyChanged;

        Platform.SetRenderer(page, null);
    }

    void UpdateBarBackgroundColor()
    {
        if (Tabbed == null || TabBar == null)
            return;

        var barBackgroundColor = Tabbed.BarBackgroundColor;

        if (!_defaultBarColorSet)
        {
            _defaultBarColor = TabBar.BackgroundColor;

            _defaultBarColorSet = true;
        }

        TabBar.BackgroundColor = barBackgroundColor.ToUIColor();
    }

    void UpdateBarTextColor()
    {
        TabBar.TextColor = Tabbed.BarTextColor.ToUIColor();
    }

    void UpdateBarIndicatorColor()
    {
        TabBar.IndicatorColor = Tabbed.BarIndicatorColor.ToUIColor();
    }
}
}
[程序集:导出呈现程序(typeof(toptabedpage),typeof(toptabedrenderer))]
命名空间Naxam.Controls.Platform.iOS
{
使用Platform=Xamarin.Forms.Platform.iOS.Platform;
使用Forms=Xamarin.Forms.Forms;
公共部分类TopTabbedRenderer:
UIViewController
{
公共静态void Init()
{
}
UIColor defaultBarColor;
bool_defaultBarColorSet;
bool_加载;
大小_队列大小;
int lastSelectedIndex;
Page=>元素作为页面;
UIPageViewController pageViewController;
受保护的UIViewController SelectedViewController;
受保护的IList视图控制器;
受保护的IPageController页控制器
{
获取{返回页;}
}
受保护的TopTabbed页选项卡
{
获取{return(toptabedpage)元素;}
}
受保护的选项卡视图选项卡栏;
私有NSLayoutConstraint选项卡高度;
公共TopTabbedRenderer()
{
ViewControllers=新UIViewController[0];
pageViewController=新的UIPageViewController(
UIPageViewControllerTransitionStyle.滚动,
UIPageViewControllerNavigationOrientation.水平,
UIPageViewControllerSpineLocation.None
);
TabBar=新TabsView
{
TranslatesAutoresizingMaskIntoConstraints=false
};
TabBar.TabsSelectionChanged+=HandleTabsSelectionChanged;
}
公共覆盖无效旋转(UIInterfaceOrientation fromInterfaceOrientation)
{
底座旋转(从接口方向);
View.SetNeedsLayout();
}
公共覆盖无效视图显示(布尔动画)
{
PageController.sendExaming();
基本视图显示(动画);
}
公共覆盖无效视图消失(布尔动画)
{
base.viewdiddemove(动画);
PageController.sendEnglishing();
}
公共覆盖无效ViewDidLoad()
{
base.ViewDidLoad();
View.AddSubview(选项卡栏);
AddChildViewController(pageViewController);
View.AddSubview(pageViewController.View);
pageViewController.View.TranslatesAutoResizengMaskintoConstraints=false;
pageViewController.DidMoveToParentViewController(此);
var views=NSDictionary.FromObjectsAndKeys(
新NSObject[]{
塔巴,
pageViewController.View
},
新NSObject[]{
(NSString)“tabbar”,
(NSString)“内容”
}
);
View.AddConstraints(NSLayoutConstraint.FromVisualFormat(“V:|-0-[tabbar]-0-[content]-0-[tabbar]”,
0,
无效的
意见),;
View.AddConstraints(NSLayoutConstraint.FromVisualFormat(“H:|-0-[tabbar]-0-|”,
0,
无效的
意见),;
View.AddConstraints(NSLayoutConstraint.FromVisualFormat(“H:|-0-[content]-0-|”,
0,
无效的
意见),;
tabBarHeight=NSLayoutConstraint.Create(
塔巴,
NSLayoutAttribute.高度,
NSLAYOUTROLATION。相等,
1, 68
);
TabBar.AddConstraint(TabBar高度);
如果(pageViewController.ViewController.Length==0
&&lastSelectedIndex>=0 | | lastSelectedIndex[assembly: ExportRenderer(typeof(TopTabbedPage), typeof(TopTabbedRenderer))]

namespace Naxam.Controls.Platform.iOS
{
using Platform = Xamarin.Forms.Platform.iOS.Platform;
using Forms = Xamarin.Forms.Forms;

public partial class TopTabbedRenderer :
    UIViewController
{
    public static void Init()
    {
    }

    UIColor _defaultBarColor;
    bool _defaultBarColorSet;
    bool _loaded;
    Size _queuedSize;
    int lastSelectedIndex;

    Page Page => Element as Page;

    UIPageViewController pageViewController;

    protected UIViewController SelectedViewController;
    protected IList<UIViewController> ViewControllers;

    protected IPageController PageController
    {
        get { return Page; }
    }

    protected TopTabbedPage Tabbed
    {
        get { return (TopTabbedPage)Element; }
    }

    protected TabsView TabBar;
    private NSLayoutConstraint tabBarHeight;

    public TopTabbedRenderer()
    {
        ViewControllers = new UIViewController[0];

        pageViewController = new UIPageViewController(
            UIPageViewControllerTransitionStyle.Scroll,
            UIPageViewControllerNavigationOrientation.Horizontal,
            UIPageViewControllerSpineLocation.None
        );

        TabBar = new TabsView
        {
            TranslatesAutoresizingMaskIntoConstraints = false
        };
        TabBar.TabsSelectionChanged += HandleTabsSelectionChanged;
    }

    public override void DidRotate(UIInterfaceOrientation fromInterfaceOrientation)
    {
        base.DidRotate(fromInterfaceOrientation);

        View.SetNeedsLayout();
    }

    public override void ViewDidAppear(bool animated)
    {
        PageController.SendAppearing();
        base.ViewDidAppear(animated);
    }

    public override void ViewDidDisappear(bool animated)
    {
        base.ViewDidDisappear(animated);
        PageController.SendDisappearing();
    }

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        View.AddSubview(TabBar);

        AddChildViewController(pageViewController);
        View.AddSubview(pageViewController.View);
        pageViewController.View.TranslatesAutoresizingMaskIntoConstraints = false;
        pageViewController.DidMoveToParentViewController(this);


        var views = NSDictionary.FromObjectsAndKeys(
            new NSObject[] {
            TabBar,
            pageViewController.View
        },
            new NSObject[] {
            (NSString) "tabbar",
            (NSString) "content"
        }
        );

        View.AddConstraints(NSLayoutConstraint.FromVisualFormat("V:|-0-[tabbar]-0-[content]-0-|",
                                                                0,
                                                                null,
                                                                views));
        View.AddConstraints(NSLayoutConstraint.FromVisualFormat("H:|-0-[tabbar]-0-|",
                                                                0,
                                                                null,
                                                                views));
        View.AddConstraints(NSLayoutConstraint.FromVisualFormat("H:|-0-[content]-0-|",
                                                                0,
                                                                null,
                                                                views));


        tabBarHeight = NSLayoutConstraint.Create(
            TabBar,
            NSLayoutAttribute.Height,
            NSLayoutRelation.Equal,
            1, 68
        );
        TabBar.AddConstraint(tabBarHeight);

        if (pageViewController.ViewControllers.Length == 0
            && lastSelectedIndex >= 0 || lastSelectedIndex < ViewControllers.Count)
        {
            pageViewController.SetViewControllers(
                new[] { ViewControllers[lastSelectedIndex] },
               UIPageViewControllerNavigationDirection.Forward,
               true, null
            );
        }

        UpdateSwipe(Tabbed.SwipeEnabled);
        pageViewController.DidFinishAnimating += HandlePageViewControllerDidFinishAnimating;
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            PageController?.SendDisappearing();

            if (Tabbed != null)
            {
                Tabbed.PropertyChanged -= OnPropertyChanged;
                Tabbed.PagesChanged -= OnPagesChanged;
                TabBar.TabsSelectionChanged -= HandleTabsSelectionChanged;
            }

            if (pageViewController != null)
            {
                pageViewController.WeakDataSource = null;
                pageViewController.DidFinishAnimating -= HandlePageViewControllerDidFinishAnimating;
                pageViewController?.Dispose();
            }
        }

        base.Dispose(disposing);
    }

    protected virtual void OnElementChanged(VisualElementChangedEventArgs e)
    {
        ElementChanged?.Invoke(this, e);
    }

    UIViewController GetViewController(Page page)
    {
        var renderer = Platform.GetRenderer(page);
        return renderer?.ViewController;
    }

    void OnPagePropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName != Page.TitleProperty.PropertyName)
            return;

        if (!(sender is Page page) || page.Title is null)
            return;

        TabBar.ReplaceItem(page.Title, Tabbed.Children.IndexOf(page));
    }

    void OnPagesChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        e.Apply((o, i, c) => SetupPage((Page)o, i), (o, i) => TeardownPage((Page)o, i), Reset);

        SetControllers();

        UIViewController controller = null;
        if (Tabbed.CurrentPage != null)
        {
            controller = GetViewController(Tabbed.CurrentPage);
        }

        if (controller != null && controller != SelectedViewController)
        {
            SelectedViewController = controller;
            var index = ViewControllers.IndexOf(SelectedViewController);
            MoveToByIndex(index);
            TabBar.SelectedIndex = index;
        }
    }

    void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == nameof(TabbedPage.CurrentPage))
        {
            var current = Tabbed.CurrentPage;
            if (current == null)
                return;

            var controller = GetViewController(current);
            if (controller == null)
                return;

            SelectedViewController = controller;
            var index = ViewControllers.IndexOf(SelectedViewController);
            MoveToByIndex(index);
            TabBar.SelectedIndex = index;
        }
        else if (e.PropertyName == TabbedPage.BarBackgroundColorProperty.PropertyName)
        {
            UpdateBarBackgroundColor();
        }
        else if (e.PropertyName == TabbedPage.BarTextColorProperty.PropertyName)
        {
            UpdateBarTextColor();
        }
        else if (e.PropertyName == TopTabbedPage.BarIndicatorColorProperty.PropertyName)
        {
            UpdateBarIndicatorColor();
        }
        else if (e.PropertyName == TopTabbedPage.SwipeEnabledColorProperty.PropertyName)
        {
            UpdateSwipe(Tabbed.SwipeEnabled);
        }
    }

    public override UIViewController ChildViewControllerForStatusBarHidden()
    {
        var current = Tabbed.CurrentPage;
        if (current == null)
            return null;

        return GetViewController(current);
    }

    void UpdateSwipe(bool swipeEnabled)
    {
        pageViewController.WeakDataSource = swipeEnabled ? this : null;
    }

    void Reset()
    {
        var i = 0;
        foreach (var page in Tabbed.Children)
        {
            SetupPage(page, i++);
        }
    }

    void SetControllers()
    {
        var list = new List<UIViewController>();
        var titles = new List<string>();
        for (var i = 0; i < Tabbed.Children.Count; i++)
        {
            var child = Tabbed.Children[i];
            var v = child as VisualElement;
            if (v == null)
                continue;

            var renderer = Platform.GetRenderer(v);
            if (renderer == null) continue;

            list.Add(renderer.ViewController);

            titles.Add(Tabbed.Children[i].Title);
        }
        ViewControllers = list.ToArray();
        TabBar.SetItems(titles);
    }

    void SetupPage(Page page, int index)
    {
        IVisualElementRenderer renderer = Platform.GetRenderer(page);
        if (renderer == null)
        {
            renderer = Platform.CreateRenderer(page);
            Platform.SetRenderer(page, renderer);
        }

        page.PropertyChanged -= OnPagePropertyChanged;
        page.PropertyChanged += OnPagePropertyChanged;
    }

    void TeardownPage(Page page, int index)
    {
        page.PropertyChanged -= OnPagePropertyChanged;

        Platform.SetRenderer(page, null);
    }

    void UpdateBarBackgroundColor()
    {
        if (Tabbed == null || TabBar == null)
            return;

        var barBackgroundColor = Tabbed.BarBackgroundColor;

        if (!_defaultBarColorSet)
        {
            _defaultBarColor = TabBar.BackgroundColor;

            _defaultBarColorSet = true;
        }

        TabBar.BackgroundColor = barBackgroundColor.ToUIColor();
    }

    void UpdateBarTextColor()
    {
        TabBar.TextColor = Tabbed.BarTextColor.ToUIColor();
    }

    void UpdateBarIndicatorColor()
    {
        TabBar.IndicatorColor = Tabbed.BarIndicatorColor.ToUIColor();
    }
}
}