Xamarin iOS基础标签页应用点击More按钮后冻结问题求助
问题描述
使用Xamarin开发了一个基础标签页应用,包含6个标签页(自动生成More菜单)。在iOS设备上,点击More进入某页面后,再次点击More按钮时应用出现冻结现象。直接添加Page而非NavigationPage作为子项时应用运行正常,但业务需要将NavigationPage作为TabbedPage的子项。
相关代码
C#代码
public partial class MainPage : TabbedPage { public MainPage() { InitializeComponent(); SetupTabs(); } void SetupTabs() { for(var index = 0; index < 6; index++) AddPage(); } void AddPage() { NavigationPage navPage = new NavigationPage(new Page()); navPage.Title = "Page"; Children.Add(navPage); } }
XAML代码
<?xml version="1.0" encoding="utf-8" ?> <TabbedPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="testTabs2.MainPage" />
问题原因
这是Xamarin.Forms在iOS平台的已知兼容性问题:当TabbedPage的子项为NavigationPage时,More菜单的导航栈会出现识别冲突。你当前所有NavigationPage的Title都重复为"Page",iOS的More菜单依赖唯一标题管理页面导航状态,重复标题会加剧栈混乱,最终导致UI线程阻塞冻结。
解决方案
1. 给每个NavigationPage设置唯一Title
这是最快速的修复方式,修改代码如下:
void SetupTabs() { for(var index = 0; index < 6; index++) AddPage(index); } void AddPage(int index) { NavigationPage navPage = new NavigationPage(new Page()); navPage.Title = $"Page {index + 1}"; // 赋予唯一标题 Children.Add(navPage); }
唯一的Title能让iOS的More菜单正确识别每个页面,避免导航栈冲突,大概率解决冻结问题。
2. 自定义iOS平台渲染器(若上述方案无效)
如果设置唯一Title后仍有问题,需要自定义TabbedPage的iOS渲染器,修复More按钮的导航逻辑:
[assembly: ExportRenderer(typeof(TabbedPage), typeof(CustomTabbedRenderer))] namespace YourAppNamespace.iOS.Renderers { public class CustomTabbedRenderer : TabbedRenderer { public override void ViewDidAppear(bool animated) { base.ViewDidAppear(animated); if (MoreNavigationController != null) { MoreNavigationController.DismissViewController(true, null); MoreNavigationController.PopToRootViewController(true); } } } }
这段代码会在每次显示TabbedPage时,重置More菜单的导航栈,避免栈堆积导致的冻结。
3. 调整页面结构(可选)
如果业务允许,可以将TabbedPage嵌套在NavigationPage内部,而非反过来:
public App() { MainPage = new NavigationPage(new MainPage()); }
这种结构能避免iOS上More菜单与NavigationPage的冲突,但会改变整体导航样式,需根据业务需求选择。
内容的提问来源于stack exchange,提问作者bcl
相关产品推荐
相关产品推荐

