我目前正在使用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)
{
}
}
现在的问题是:
与Android生命周期相同,相同的代码在Android中也能正常工作
在调试模式下可以看到的不同
我尝试过的一些事情是:
最佳答案
如您所说,由于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,您可以检查它。让我知道它是否有效。