NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Framework/UI/UIWindow.DefaultBackButton.cs

118 lines
6.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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
}