【Unity UI 进阶】仿 Element UI 打造企业级 Unity UI 组件库(10)
环境与工具说明
| 项 | 说明 |
|---|---|
| 代码生成 | 本系列组件库代码由Cursor(AI 编程助手)辅助生成与迭代,再结合工程内联调、重构落地 |
| Unity 版本 | 2022.3.50f1c1(Unity 2022.3 LTS) |
| UI 框架 | UGUI(UnityEngine.UI) + TextMeshPro |
| 示例工程 | EleUnityUI(仿 Element UI 企业级组件库) |
建议使用Unity 2022.3 LTS同系列版本打开工程。上篇(09)讲完
EleAccordion;本篇是EleDialog对话框:模态遮罩、表单字段、确认/取消,以及和Table 行编辑弹窗的复用关系。
Dialog 对话框:模态 / 非模态、标题拖拽、右下角缩放、边缘收起
后台里删一行、改一行、批量改字段,几乎都绕不开「弹窗」。Element 的 Dialog 心智是:
- 遮罩可选:Modal 挡住底层;Modeless 可继续点表格
- 确认 / 取消:危险操作要二次确认
- 表单窗:按字段配置生成 Input / Select / Number…
- 可拖可缩:标题栏移动、右下角改尺寸;需要时可收到边缘
EleDialog按同一模型实现:Alert / Confirm / Form 共用一副壳;Table 行编辑不另写弹窗,只调ShowForm。
本篇覆盖:
- 模态遮罩(
EleDialogMode.Modal/Modeless) - 表单字段与校验
- 确认 / 取消回调
- 标题拖拽 / 右下角缩放 / 边缘收起还原
- 与 Table 行编辑的复用关系
- Prefab Generate 约定
涉及文件:
| 能力 | 主要文件 |
|---|---|
| 运行时壳与交互 | Runtime/Dialog/EleDialog.cs |
| 标题拖 / 缩放把手 | EleDialogTitleDrag.cs/EleDialogResizeHandle.cs |
| 示例配置 | Runtime/Dialog/EleDialogModels.cs、EleDialogConfigAsset.cs |
| 示例宿主 | Runtime/Dialog/EleDialogSampleDemoHost.cs |
| 示例生成 | Editor/Dialog/EleDialogSampleGenerator.cs |
| 表单配置类型 | Runtime/Tables/EleTableModels.cs(EleDialogConfig/EleFormFieldConfig) |
| Table 打开弹窗 | Runtime/Tables/EleTable.Dialogs.cs |
颜色走设计变量:遮罩半透明黑、面板PanelBg、标题栏HeaderBg、主按钮 Primary。
工程约定:不改第三方插件;新增 C# 写中文注释;Generate 烘焙EleDialogHost壳(Overlay + Panel + ResizeHandle),运行时缺引用打日志,不在 Demo 路径「缺啥建啥」。
一、整体结构
1. Prefab 层级(示例)
EleDialogSample ├── DemoPanel ← 左侧演示按钮 + 日志 │ ├── BtnAlert / BtnConfirm │ ├── BtnFormModal / BtnFormModeless │ └── Log └── EleDialogHost ← EleDialog(铺满,sortingOrder 置顶) ├── Overlay ← 模态遮罩(非模态时隐藏) └── Panel ├── TitleBar ← Title + Collapse(—/□) + Close(×) ├── Body │ ├── Message ← Alert/Confirm 文案;表单校验提示 │ └── Form ← 动态字段行 ├── Footer ← Cancel / Ok └── ResizeHandle ← 右下角缩放(ignoreLayout)2. 数据流
ShowAlert / ShowConfirm / ShowForm → EnsureShell(重绑已烘焙壳) → ApplyChrome(标题、按钮、模态、尺寸、可拖/缩/收) → 用户交互 → 拖 TitleBar → anchoredPosition → 拖 ResizeHandle → sizeDelta(夹最小尺寸) → 点 — → 藏 Body/Footer,贴最近边缘成条;点 □ 还原 → Ok → CollectForm + 校验 → onSubmit / onOk → Cancel / × → onCancel → Close业务最小接入(独立使用):
vardlg=EleDialog.Ensure(parent);dlg.ApplyChromeOptions(draggable:true,resizable:true,collapsible:true);dlg.ShowConfirm("确认","确定删除?",onOk:()=>Delete(),onCancel:null);Table 侧更常见:
table.OpenConfiguredDialog("editRow",newList<EleTableRowData>{row.Data});// 或行操作 actionKind=Edit → 默认 key = openDialogKey ?? "editRow"二、配置模型
1.EleDialogConfig(与 Table 共用)
| 字段 | 含义 |
|---|---|
key | 工具栏 / 行操作openDialogKey引用 |
title | 标题栏文案 |
mode | Modal/Modeless |
width/minHeight | 初始尺寸 |
confirmText/cancelText/showCancel | 底栏按钮 |
bindSelectedRow | 打开时用选中行第一条填字段 |
draggable/resizable/collapsible | 拖、缩、收起 |
fields | EleFormFieldConfig列表 |
2. 字段类型EleFormFieldType
| 类型 | UI |
|---|---|
| Input | 单行 TMP_InputField |
| Number | 数字内容类型 |
| TextArea | 多行 |
| Select | 按钮轮换选项(值存隐藏 Input) |
| Checkbox | Toggle,提交"1"/"0" |
必填失败时在Message区用危险色提示,不关窗。
3. 示例EleDialogSampleConfig
独立 Demo 用:默认 chrome 开关 +demoForm(结构与 TableeditRow对齐,便于对照博文 04)。
三、模态与非模态
| 模式 | Overlay | 底层可否操作 |
|---|---|---|
| Modal | 半透明黑、raycastTarget=true | 否(先关窗) |
| Modeless | 隐藏 / 透明、不挡射线 | 是(可继续点表格或 Demo 按钮) |
ShowAlert/ShowConfirm用bool modal参数;ShowForm读config.mode。
示例按钮:
- 表单(模态)→
EleDialogMode.Modal - 表单(非模态)→
EleDialogMode.Modeless
四、拖拽、缩放、边缘收起
1. 拖标题
EleDialogTitleDrag挂在TitleBar:左键拖动把eventData.delta换算成 Canvas 本地增量,写入_panel.anchoredPosition,并夹在 Host 矩形内。收起成条后仍可拖,松手按最近边再贴齐。
2. 右下角缩放
EleDialogResizeHandle锚在 Panel 右下,LayoutElement.ignoreLayout=true避免被竖排布局挤走。拖动时增大sizeDelta,并按中心枢轴补偿anchoredPosition,夹minWidth/minHeight。
3. 边缘收起
| 操作 | 行为 |
|---|---|
| 点标题栏— | 记住位置与尺寸;隐藏 Body / Footer / ResizeHandle;缩成条贴最近边 |
| 点□ | 还原尺寸与位置,重新显示内容区 |
贴边枚举:EleDialogDockEdge= Left / Right / Top / Bottom。
五、与 Table 行编辑的复用关系
这是本篇重点:不要为表格再写一套弹窗。
行操作 Edit / 工具栏 openDialogKey → EleTable.OpenConfiguredDialog(key, contextRows) → config.FindDialog(key) → EleDialogConfig → EleDialog.Ensure(table.transform) // Host 名 EleDialogHost → ShowForm(cfg, seedRow, onSubmit, onCancel) → OnDialogSubmitted(EleDialogSubmitRequest)| 能力 | Dialog 独立示例 | Table 行编辑 |
|---|---|---|
| 壳 UI | Generate 烘焙EleDialogHost | Ensure复用同组件 |
| 配置 | EleDialogSampleConfig.demoForm | EleTableConfig.dialogs |
| 种子数据 | Demo 构造EleTableRowData | bindSelectedRow→ 选中行 |
| 提交 | Demo 打日志 | OnDialogSubmitted→ 业务改行 / 调接口 |
| 确认框 | ShowConfirm | 行删除confirmBeforeExecute等同壳 |
因此改遮罩、拖拽、缩放、收起,表格编辑窗一并受益。字段模型仍放在EleTableModels(历史原因),运行时组件在Runtime/Dialog/。
六、Prefab 生成与菜单
1. 菜单
EleUnityUI → Samples → Dialog → Generate EleDialog Sample EleUnityUI → Samples → Dialog → Spawn EleDialog Preview In Scene EleUnityUI → Samples → Dialog → Reset EleDialog Config To Preset GameObject → EleUnityUI → Dialog → SampleSpawn不会在缺 Prefab 时自动 Generate。
2. Generate 烘焙什么
- 左侧
DemoPanel与四个入口按钮 EleDialogHost:Overlay、Panel、TitleBar(含 Collapse/Close)、Body、Form、Footer、ResizeHandleEleDialogSampleDemoHost序列化引用
3. 运行时约定
// ✅ 壳已烘焙,EnsureShell 只 Rebinddialog.EnsureShell();dialog.ShowForm(cfg,seed,onSubmit,onCancel);// ❌ Demo 里发现没有 Panel 就临时拼一棵树缺dialog引用:Debug.LogError("[EleDialog] 缺少 dialog 引用,请重新 Generate Prefab")。
七、API 一览
| API / 事件 | 说明 |
|---|---|
Ensure(parent) | 获取/创建EleDialogHost |
ApplyChromeOptions(...) | 拖 / 缩 / 收起与最小尺寸 |
ShowAlert/ShowConfirm | 警告 / 确认 |
ShowForm(config, seed, onSubmit, onCancel) | 表单窗 |
Close(invokeCancel) | 关闭 |
ToggleCollapse | 收起 ↔ 还原 |
CollectForm | 收集字段值 |
IsOpen/IsCollapsed/IsModal | 状态 |
Table:OpenConfiguredDialog/OnDialogSubmitted | 行编辑入口 |
八、落地检查清单
- Generate 后有
EleDialogSample.prefab,含EleDialogHost/Panel/ResizeHandle - Spawn 后点 Alert / Confirm / 两种表单均能打开
- 模态时遮罩挡住 Demo;非模态时可再点其它按钮
- 拖标题可移动;拖右下角可改大小(不低于最小尺寸)
- 点 — 收到边缘成条;点 □ 还原
- 表单必填为空时提示且不关闭;提交后日志有字段值
- Table 行「编辑」仍打开同一套
EleDialog(见博文 04)
九、小结
- EleDialog= 一副壳覆盖 Alert / Confirm / Form
- Modal / Modeless只切换 Overlay,不换组件
- 拖标题、右下角缩放、边缘收起是窗体 chrome,与表单字段正交
- Table 行编辑=
openDialogKey→ 同一ShowForm,业务听OnDialogSubmitted
系列回顾与下篇
| 篇 | 内容 |
|---|---|
| 04 | Table 下:工具栏、弹窗入口、OnDialogSubmitted |
| 05 | Tabs:Panel_{tabCode} |
| 09 | Accordion:手风琴与 Tabs 边界 |
| 10 | Dialog:模态、表单、拖缩收起、与 Table 复用(本文) |
11|反馈类补齐:EleMessage 页面提示 + Tooltip 用法:UGUI 无 Message/Alert/Tooltip —— 新建轻量EleMessage;Tooltip 基于已有EleUiTooltip写清配置与用法(不另造一层壳)。
若你也在纠结「表格编辑要不要单独做 Page」:字段少、要挡操作 →Modal Dialog;要对照表格边改边看 →Modeless;整页复杂向导 → 另开路由/面板,别硬塞 Dialog。