跳转到正文

运行时 API 参考 ​

本页介绍 UIManager 的运行时 API,包括面板加载、打开、关闭、查询、Surface 管理、输入焦点和运行时事件。

运行时入口:FinkFramework.Runtime.UI.UIManager.Instance。泛型面板类型必须继承 BasePanel。

面板加载 ​

API返回值说明
Preload<T>()T同步预加载;首次支持 Resources 或允许同步加载的 Addressables
PreloadAsync<T>()UniTask<T>异步加载并保持隐藏
Open<T>()T同步打开;非 Resources 来源须先完成预加载
OpenAsync<T>()UniTask<T>异步加载并打开
Open<T, TArgs>(args)T同步打开并注入参数
OpenAsync<T, TArgs>(args)UniTask<T>异步打开并注入参数

所有加载 API 都有接收 UIOpenOptions 的重载。

选择加载 API ​

需求推荐 API结果
首次打开并立即显示OpenAsync<T>()等待资源、实例和进入过渡完成
预先准备资源PreloadAsync<T>()完成实例化和初始化,但保持隐藏
Resources 首次同步加载Open<T>() / Preload<T>()在当前调用中完成操作
Addressables 首次同步预加载Preload<T>()全局后端须为 Addressables,且开启 Allow Sync Load
非 Resources 面板同步打开预加载完成后调用 Open<T>()复用相同 Surface / InstanceId 下的已加载实例
需要传入业务数据OpenAsync<T, TArgs>(args)在 OnEnter 前调用 ApplyArgs

UI 层对同步首次加载有额外限制:AssetBundle 和其他自定义协议不支持同步首次预加载;Addressables 开启 Allow Sync Load 也不允许用 Open<T>() 直接首次加载。预加载未完成、返回 null 或 Surface / InstanceId 不一致时,同步打开不能复用目标实例,会记录错误并返回 null。

需要等待异步资源时,使用 UniTask 版本;调用方传入的 CancellationToken 只取消本次等待,不会取消其他调用方共享的底层加载任务。

自定义面板地址 ​

CustomPanelAssetPathResolver 类型为 Func<Type, string>,用于 UI 加载来源为 Custom 或跟随 Custom 资源后端时,将面板类型转换为完整资源地址。首次加载前设置解析器,并通过 ResManager.Instance.AddProvider(...) 注册对应协议 Provider。完整配置见 面板加载来源。

预加载与打开的区别 ​

csharp
// 资源已实例化,但保持隐藏,不进入显示生命周期
await UIManager.Instance.PreloadAsync<SettingsPanel>();

// 复用已预加载的实例并进入显示流程
await UIManager.Instance.OpenAsync<SettingsPanel>();

预加载不会调用 OnEnter,也不会将 Page 加入导航栈。面板真正打开时,系统才应用当前的 Surface、层级、显示模式、焦点和导航选项。

面板查询 ​

csharp
MainPanel panel = UIManager.Instance.Get<MainPanel>();

if (UIManager.Instance.TryGet<MainPanel>(out MainPanel result))
{
    result.Refresh();
}

bool opened = UIManager.Instance.IsOpen<MainPanel>();

if (UIManager.Instance.TryGetState<MainPanel>(out UIPanelState state))
{
    UnityEngine.Debug.Log(state);
}

需要查询非默认实例或非 Main Surface 时,传入 UIInstanceId 和 UISurfaceId:

csharp
MapPanel panel = UIManager.Instance.Get<MapPanel>(
    instanceId: "Detail",
    surfaceId: "WorldMap");

查询 API 不会创建面板:

  • Get<T> 找不到实例时返回 null;
  • TryGet<T> 通过返回值区分是否找到;
  • IsOpen<T> 只对 Opening、Active 和 Paused 状态返回 true;
  • TryGetState<T> 找不到记录时返回 false,输出状态为 Disposed。

同一类型在不同 SurfaceId 或 InstanceId 下是不同面板实例,查询时必须使用与打开时相同的标识。

关闭与返回 ​

csharp
UIManager.Instance.Close<MainPanel>();
await UIManager.Instance.CloseAsync<MainPanel>();

UIManager.Instance.Back();
await UIManager.Instance.BackAsync();

UIManager.Instance.CloseSurface("WorldMap");
UIManager.Instance.CloseAll();
UIManager.Instance.ClearAll();

Close 和 CloseAsync 的 destroy 参数可以强制销毁实例。

CloseAsync 会等待面板实现的退出过渡;同步 Close 会立即完成退出操作。关闭后是否保留实例由打开时的 UICachePolicy 决定,destroy: true 可以覆盖缓存策略并立即释放该实例。

Back / BackAsync 的处理顺序为:先让最上层 Modal 处理返回,再处理当前页面栈栈顶;如果面板实现 IUIBackHandler 并返回 true,则返回请求由面板消费,不会继续执行默认关闭。

API作用
Close<T>()关闭默认实例和 Main Surface 上的面板
Close<T>(instanceId, surfaceId)关闭指定实例
Close(UIPanelKey)按完整身份关闭面板
CloseSurface(surfaceId)关闭指定 Surface 上的全部面板
CloseAll()关闭所有面板,默认保留可缓存实例
ClearAll()关闭并销毁所有面板实例

Surface 管理 ​

csharp
UIManager.Instance.RegisterSurface(
    "WorldMap",
    worldCanvas,
    worldPanelRoot,
    replace: false,
    lifetime: UISurfaceLifetime.Scene);

UIManager.Instance.UnregisterSurface("WorldMap");

Main Surface 由框架保留,不能由业务覆盖或注销。

注册自定义 Surface 后,打开选项中的 SurfaceId 必须使用相同值。注册时如果 Canvas 没有事件相机,框架会尝试为 ScreenSpaceCamera 设置 UI Camera,为 WorldSpace 设置主相机;复杂场景建议显式配置 Canvas 的 EventCamera。

输入与焦点 ​

csharp
UIManager.Instance.SetInputMode(UIInputMode.Navigation);
UIManager.Instance.SetNavigationInteractionEnabled(false);
UIManager.Instance.Focus<MainPanel>();

UIInputMode mode = UIManager.Instance.InputMode;
bool navigationEnabled = UIManager.Instance.NavigationInteractionEnabled;
InputDeviceType device = UIManager.Instance.CurrentInputDevice;

Focus<T> 只会尝试将导航焦点移动到可见面板。如果面板没有有效的 Selectable,或者目标面板被 Modal 交互阻断,聚焦请求会失败。NavigationInteractionEnabled 关闭时仍可使用鼠标和触摸点击。

运行时事件 ​

csharp
UIManager.Instance.PanelStateChanged += (key, state) => { };
UIManager.Instance.InputModeChanged += mode => { };
UIManager.Instance.InputDeviceChanged += (previous, current) => { };

事件适合调试器、输入提示和自动化测试。业务订阅外部事件时,应在面板的 OnDispose 中解除订阅,避免缓存实例销毁后仍保留委托引用。

面板状态 ​

UIPanelState 的状态含义如下:

状态含义
Loading正在加载资源或创建实例
Hidden实例已准备好但当前未显示
Opening正在执行进入过渡
Active当前可见并处于活动状态
PausedPage 被上层 Page 覆盖,实例仍保留
Closing正在执行退出过渡
Disposed实例已释放
Failed加载或打开流程失败

运行时排查可以同时查看 UIPanelState、UIPanelKey 和 UIPanelSnapshot.AssetPath,确认是资源定位问题、Surface 问题还是显示流程问题。

关键类型 ​

类型用途
UIOpenOptions描述面板打开方式
UIPanelKey面板类型、实例和 Surface 的完整身份
UIPanelContext面板实例的运行时上下文
UIPanelState面板运行时状态
UIPanelSnapshot面板只读运行时快照
UISurfaceSnapshotSurface 只读运行时快照
UISurfaceRoot将场景 Canvas 注册为 Surface
IUIArgsReceiver<TArgs>接收打开参数
IUIBackHandler消费返回请求
IUITransition接入面板过渡动画
UIModalBackdrop配置 Modal 遮罩
UISafeArea适配屏幕安全区域