118 lines
6.0 KiB
C#
118 lines
6.0 KiB
C#
|
|
using Cysharp.Threading.Tasks;
|
|||
|
|
using UnityEngine;
|
|||
|
|
using UnityEngine.UI;
|
|||
|
|
using PhxhSDK;
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
╔═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
|
|||
|
|
║ UIWindow 默认Back按钮处理模块 (Default Back Button) ║
|
|||
|
|
╠═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
|
|||
|
|
║ ║
|
|||
|
|
║ 【功能说明】 ║
|
|||
|
|
║ 处理UIWindow的默认"返回"按钮的自动绑定和点击逻辑。 ║
|
|||
|
|
║ 通过约定节点名(BtnBack、BackButton、BtnReturn),框架自动识别并绑定按钮。 ║
|
|||
|
|
║ ║
|
|||
|
|
║ 【使用方式】 ║
|
|||
|
|
║ 1. 默认使用:在预制体中创建约定名称的按钮,无需代码 ║
|
|||
|
|
║ 2. 自定义节点名:重写 DefaultBackButtonNames 虚属性 ║
|
|||
|
|
║ 3. 自定义行为:重写 OnBack() 虚方法(在 UIWindow.Lifecycle.cs 中定义) ║
|
|||
|
|
║ ║
|
|||
|
|
║ 【默认行为】 ║
|
|||
|
|
║ 点击返回按钮 → 调用 Back() → 触发 OnBack() → 使用 BackStrategy ║
|
|||
|
|
║ 与Android返回键/ESC键行为完全一致 ║
|
|||
|
|
║ ║
|
|||
|
|
╚═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// UI窗口基类 - 默认Back按钮处理部分
|
|||
|
|
/// 负责自动识别和绑定预制体中的"返回"按钮
|
|||
|
|
/// </summary>
|
|||
|
|
public abstract partial class UIWindow
|
|||
|
|
{
|
|||
|
|
#region Default Back Button - 默认返回按钮自动绑定
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 默认返回按钮的节点名配置(子类可重写)
|
|||
|
|
/// 默认支持:BtnBack、BackButton、BtnReturn
|
|||
|
|
/// </summary>
|
|||
|
|
protected virtual string[] DefaultBackButtonNames => new[] { "BtnBack", "BackButton", "BtnReturn" };
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 绑定所有配置的默认返回按钮
|
|||
|
|
/// 在 DoInit() 阶段自动调用
|
|||
|
|
/// 返回按钮会调用 Back() 方法,触发 OnBack() 虚方法
|
|||
|
|
/// </summary>
|
|||
|
|
private void BindDefaultBackButtons()
|
|||
|
|
{
|
|||
|
|
foreach (var buttonName in DefaultBackButtonNames)
|
|||
|
|
{
|
|||
|
|
TryBindBackButton(buttonName);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 尝试绑定返回按钮(节点不存在时静默跳过)
|
|||
|
|
/// 绑定后,点击按钮会调用 Back() 方法,触发 OnBack() 虚方法
|
|||
|
|
/// </summary>
|
|||
|
|
private void TryBindBackButton(string nodeName)
|
|||
|
|
{
|
|||
|
|
var trans = transform.Find(nodeName);
|
|||
|
|
if (trans)
|
|||
|
|
{
|
|||
|
|
var btn = trans.GetComponent<Button>();
|
|||
|
|
if (btn)
|
|||
|
|
{
|
|||
|
|
// 绑定到 Back() 方法,会触发 OnBack() 虚方法
|
|||
|
|
BindButton(btn, () => Back().Forget());
|
|||
|
|
DebugUtil.Log("✅ 已自动绑定返回按钮: {0} -> {1} -> Back()", WindowName, nodeName);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
|
|||
|
|
#region Back Logic - 返回逻辑处理
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 处理返回键(公共接口,不可重写)
|
|||
|
|
/// 框架会按照从上到下的顺序调用所有可见窗口的Back()方法,
|
|||
|
|
/// 直到某个窗口处理并返回true为止
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns>是否成功处理返回键(true表示已处理,false表示未处理,继续向下传递)</returns>
|
|||
|
|
public async UniTask<bool> Back()
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
return await OnBack();
|
|||
|
|
}
|
|||
|
|
catch (System.Exception e)
|
|||
|
|
{
|
|||
|
|
DebugUtil.LogError("window : {0} back error: {1}\n===Stack===\n{2}\n======", WindowName, e.Message, e.StackTrace);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 返回键处理(虚方法,子类可重写)
|
|||
|
|
/// 默认通过返回策略模式处理
|
|||
|
|
/// </summary>
|
|||
|
|
/// <returns>是否成功处理返回键(true表示已处理,false表示未处理,继续向下传递)</returns>
|
|||
|
|
protected virtual async Cysharp.Threading.Tasks.UniTask<bool> OnBack()
|
|||
|
|
{
|
|||
|
|
if (!GraphicRaycasterManager.IsEnableGraphicRaycaster)
|
|||
|
|
return true;
|
|||
|
|
|
|||
|
|
// 使用策略模式处理返回键
|
|||
|
|
if (BackStrategy != null)
|
|||
|
|
{
|
|||
|
|
return await BackStrategy.HandleBack(this);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endregion
|
|||
|
|
}
|
|||
|
|
|