如何在Xamarin.Forms中隐藏标签栏? [英] How to hide Tab Bar on push in Xamarin.Forms?

查看:425
本文介绍了如何在Xamarin.Forms中隐藏标签栏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近几天,我在iOS的Xamarin.Forms中使用TabbedPage苦苦挣扎.我发现了一些类似的解决方案: https://forums.xamarin.com/discussion/20901/Hide-tab-bar-on-Push

I'm struggling for last few days with TabbedPage in Xamarin.Forms on iOS. I found some solutions like those: https://forums.xamarin.com/discussion/20901/hide-tab-bar-on-push

但是,它们都不起作用.我还尝试将TabbedRenderer子类化,并将TabBar高度设置为0.它可以工作,但是如果我在NavigationPage.Pushed事件处理程序中隐藏TabBar,则会有一些延迟,例如TableView的底部有空白.

However, none of them works well. I also tried to subclass TabbedRenderer and set TabBar height to 0. It works, but if I hide TabBar in NavigationPage.Pushed event handler, there's some delay and for example TableView has blank space on the bottom.

如果我尝试覆盖NavigationRenderer并在PushViewController/PopViewController方法中隐藏/显示选项卡栏,则有时会失败.例如,如果我来回快速导航,则未调用方法PopViewController,NavigationStack损坏,Tab Bar也未还原.

If I try to override NavigationRenderer and hide/show Tab Bar in PushViewController/PopViewController methods it sometimes fails. For example if I navigate fast back and forth, method PopViewController is not invoked, NavigationStack is broken and Tab Bar is not restored.

我认为唯一好的解决方案是使该属性起作用:UIViewController.HidesBottomBarWhenPushed.但是,我不知道该怎么做,因为在渲染器中设置/覆盖它不起作用.

I think that the only good solution would be to make this property work: UIViewController.HidesBottomBarWhenPushed. However, I have no idea how to do it, because setting/overriding it in renderers doesn't work.

没有人设法成功地展示&隐藏TabBar?

Did anybody manage to successfuly show & hide TabBar?

推荐答案

我设法实现了一个解决方案,该解决方案隐藏了TabBar后用空格解决了该问题.您可以在这篇文章中阅读有关它的更多详细信息. .

I managed to implement a solution which fixes the issue with blank space after hiding TabBar. You can read more details about it in this article.

要解决此问题,我们只需要布置所有ChildViewControllers.这是我的自定义TabbedPage及其TabbedPageRenderer的示例实现.

To solve the problem we just need to layout all ChildViewControllers. Here is my sample implementation of a custom TabbedPage and its TabbedPageRenderer.

HideableTabbedPage.cs:

using System;
using Xamarin.Forms;

namespace HideTabBar.Controls
{
    public class HideableTabbedPage : TabbedPage
    {
        public static readonly BindableProperty IsHiddenProperty =
            BindableProperty.Create(nameof(IsHidden), typeof(bool), typeof(HideableTabbedPage), false);

        public bool IsHidden
        {
            get { return (bool)GetValue(IsHiddenProperty); }
            set { SetValue(IsHiddenProperty, value); }
        }
    }
}

HideableTabbedPageRenderer.cs:

using System;
using System.ComponentModel;
using System.Threading.Tasks;
using HideTabBar.Controls;
using HideTabBar.iOS.CustomRenderer;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(HideableTabbedPage), typeof(HideableTabbedPageRenderer))]
namespace HideTabBar.iOS.CustomRenderer
{
    public class HideableTabbedPageRenderer : TabbedRenderer
    {
        private bool disposed;
        private const int TabBarHeight = 49;

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

            if (e.OldElement == null)
            {
                this.Tabbed.PropertyChanged += Tabbed_PropertyChanged;
            }
        }

        private void Tabbed_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == HideableTabbedPage.IsHiddenProperty.PropertyName)
            {
                this.OnTabBarHidden((this.Element as HideableTabbedPage).IsHidden);
            }
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
            this.disposed = true;
        }

        private async void OnTabBarHidden(bool isHidden)
        {
            if (this.disposed || this.Element == null || this.TabBar == null)
            {
                return;
            }

            await this.SetTabBarVisibility(isHidden);
        }

        private async Task SetTabBarVisibility(bool hide)
        {
            this.TabBar.Opaque = false;
            if (hide)
            {
                this.TabBar.Alpha = 0;
            }

            this.UpdateFrame(hide);

            // Show / Hide TabBar
            this.TabBar.Hidden = hide;
            this.RestoreFonts();

            // Animate appearing 
            if (!hide)
            {
                await UIView.AnimateAsync(0.2f, () => this.TabBar.Alpha = 1);
            }
            this.TabBar.Opaque = true;

            this.ResizeViewControllers();
            this.RestoreFonts();
        }

        private void UpdateFrame(bool isHidden)
        {
            var tabFrame = this.TabBar.Frame;
            tabFrame.Height = isHidden ? 0 : TabBarHeight;
            this.TabBar.Frame = tabFrame;
        }

        private void RestoreFonts()
        {
            // Workaround to restore custom fonts:

            foreach (var item in this.TabBar.Items)
            {
                var text = item.Title;
                item.Title = "";
                item.Title = text;
            }
        }

        private void ResizeViewControllers()
        {
            foreach (var child in this.ChildViewControllers)
            {
                child.View.SetNeedsLayout();
                child.View.SetNeedsDisplay();
            }
        }
    }
}  

最终结果:

这篇关于如何在Xamarin.Forms中隐藏标签栏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆