我目前正在使用Xamarin.Forms开发应用程序。我在iOS中面临一些严重的问题。我的根页面是TabbedPage,我想使我的标签在整个应用程序中可见。因此,我将MainPage设置如下

应用程式

MainPage = new NavigationPage(new MyTabbedPage());

MyTabbedPage.cs
Children.Add(new NavigationPage(new FirstTabbedPage()));
Children.Add(new NavigationPage(new SecondTabbedPage()));
Children.Add(new NavigationPage(new ThirdTabbedPage()));

FirstTabbedPage和SecondTabbedPage都使用DevExpress.Mobile显示了DataGrid。在从网格中点击任意行时,我正在导航到另一个ContentPage,在Root选项卡中说MyContentPage。

SecondTabbePage.cs
private async void Grid_RowTap(object sender, RowTapEventArgs e)
        {
        //Some code logic, to get data from server
            await Navigation.PushAsync(new MyContentPage());
        }

例如,我要从SecondTabbedPage导航到MyContentPage。从ContentPage,我导航到FirstTabbedPage。现在,如果我单击SecondTabbedPage,将显示MyContentPage,但我不希望出现这种情况,因此,我正在使用MyContentPage的OnDisappearing方法从NavigationStack中删除页面,如下所示:

MyContentPage.cs
protected override void OnDisappearing()
        {
            base.OnDisappearing();

            //Clear Navigation Stack, clicking on tab page should always
            //go to corresponding page
            try
            {
                var existingPages = Navigation.NavigationStack.ToList();
                foreach (var page in existingPages)
                {
                    //existingPages count should be greater than 1, so that this will never be root page. Otherwise removing root page will throw exception
                    if (string.Compare(page.GetType().Name, "MyContentPage", StringComparison.OrdinalIgnoreCase) == 0 && existingPages.Count > 1)
                    {
                        Navigation.RemovePage(page);
                    }

                }
         //Just to check whether page was removed or not, but still was able to see MyContentPage even after removing it from Navigation Stack
             var existingPages = Navigation.NavigationStack.ToList();
            }
            catch(Exception ex)
            {

            }
        }

现在的问题是:
  • 即使在调用RemovePage(MyContentPage)之后,我也可以在Debug模式下看到该页面。
  • 由于此行为,请等待Navigation.PushAsync(new MyContentPage());。尽管它执行代码没有任何异常,但第二次也没有导航到MyContentPage。

  • 与Android生命周期相同,相同的代码在Android中也能正常工作
    在调试模式下可以看到的不同

    我尝试过的一些事情是:
  • 当我看到NavigationPage中的TabbedPage不是适用于iOS的良好设计时,已从MainPage(TabbedPage)中删除了NavigationPage。
  • 删除了子项上的NavigationPage,但导航到MyContentPage后未显示选项卡式图标
  • 尝试在FirstTabbedPage的OnAppearing事件中从NavigationStack中删除MyContentPage。
  • 最佳答案

    如您所说,由于Android生命周期不同于iOS,我建议您通过在iOS中使用自定义渲染器来达到要求。

    您应该为自己的MyTabbedPage创建一个自定义渲染器,然后在ViewControllerSelected事件中,从ContentPage中删除您的NavigationStack

    [assembly: ExportRenderer(typeof(MainPage), typeof(myTabbarRenderer))]
    namespace TabbedPageWithNavigationPage.iOS
    {
        class myTabbarRenderer : TabbedRenderer
        {
            private MainPage _page;
            protected override void OnElementChanged(VisualElementChangedEventArgs e)
            {
                base.OnElementChanged(e);
    
                if (e.NewElement != null)
                {
                    _page = (MainPage)e.NewElement;
                }
                else
                {
                    _page = (MainPage)e.OldElement;
                }
    
                try
                {
                    var tabbarController = (UITabBarController)this.ViewController;
                    if (null != tabbarController)
                    {
                        tabbarController.ViewControllerSelected += OnTabbarControllerItemSelected;
                    }
                }
                catch (Exception exception)
                {
                    Console.WriteLine(exception);
                }
            }
    
            private async void OnTabbarControllerItemSelected(object sender, UITabBarSelectionEventArgs eventArgs)
            {
                if (_page?.CurrentPage?.Navigation != null && _page.CurrentPage.Navigation.NavigationStack.Count > 0)
                {
                    await _page.CurrentPage.Navigation.PopToRootAsync();
                }
    
            }
        }
    }
    

    对于Android,添加Device.RuntimePlatform == Device.Android以确保该代码仅适用于Android平台:
    protected override void OnDisappearing()
    {
        base.OnDisappearing();
    
        //Clear Navigation Stack, clicking on tab page should always
        //go to corresponding page
    
        if (Device.RuntimePlatform == Device.Android)
        {
            try
            {
                var existingPages = Navigation.NavigationStack.ToList();
                foreach (var page in existingPages)
                {
                    //existingPages count should be greater than 1, so that this will never be root page. Otherwise removing root page will throw exception
                    if (string.Compare(page.GetType().Name, "UpcomingAppointmentsPage", StringComparison.OrdinalIgnoreCase) == 0 && existingPages.Count > 1)
                    {
                        Navigation.RemovePage(page);
                    }
    
                }
            }
            catch (Exception ex)
            {
    
            }
        }
    }
    

    我编写了一个演示here,您可以检查它。让我知道它是否有效。

    10-07 22:17