123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- import { _decorator, Component, director,Node, Vec3, Widget} from 'cc';
- import { Singleton } from './Singleton';
- import { Constants } from '../../data/Constants';
- import { Utils } from '../../utils/Utils';
- import { ResUtil } from '../../utils/ResUtil';
- const { ccclass, property } = _decorator;
- interface PageActive{
- show: () => {},
- hide: () => {},
- back: () => {},
- }
- @ccclass("uiManager")
- export class uiManager extends Singleton {
- //tabbar pages主页面节点放在这个容器中
- private pageUIs: string = 'pageUIs';
- //pop dialog出来的节点放在这个容器中
- private popUIs: string = 'popUIs';
- //页面缓存
- public panels = new Map <string, Node>();
- /**
- * 展示场景
- * @param sceneName 场景名字
- * @param delay 延迟的时间
- */
- public showScene(sceneName: string, delay: number = 0.1): void {
- if (delay) {
- setTimeout(() => {
- director.loadScene(sceneName);
- }, delay * 1000);
- } else {
- director.loadScene(sceneName);
- }
- }
- /**
- * 展示一个resources资源包里的节点
- * @param path Prefab的路径名称
- * @param args 给组建传递的参数
- * @param cb 展示完成的回调函数
- * @returns
- */
- public async show(path: string, args?: any, cb?: Function): Promise<Node>{
- const pageName: string = path.split('/').pop();
- if (!args) {args = [];}
- const scriptName = pageName.replace(/^\w/, (c) => c.toUpperCase());
- let panel: any = this.panels.get(path);
- if(!panel){
- panel = await ResUtil.loadRes(path);
- this.panels.set(path, panel);
- }
- if (!panel || !(panel instanceof Node)) return;
- //动态添加页面的路径path信息,在关闭和销毁的时候用到
- panel['_uiPath'] = path;
- let isMain = Object.values(Constants.mainUIs).includes(path);
- const name: string = isMain ? this.pageUIs : this.popUIs;
- let parent:Node = this.getCurentSceneRoot();
- parent = Utils.findName(parent,name) ?? parent;
- panel.parent = parent;
- panel.active = true;
- panel.getComponent(Widget)?.updateAlignment();
- if(isMain){
- parent.children.forEach((e:Node) => {
- e.setPosition(new Vec3(e.name == pageName ? 0 : 500000,0,1));
- });
- }else{
- panel.setSiblingIndex(parent.children.length);
- }
- const comp = panel.getComponent(scriptName);
- if (comp && (comp as Component & PageActive)['show']){
- (comp as Component & PageActive)['show'].apply(comp, args);
- }
- if(typeof cb === 'function') {cb?.(panel)};
- }
- /**
- * 根据堆栈页面顺序返回到某一个页面
- * @param path 返回某一个界面
- * @param args 返回的附带参数
- * @param cb 回调
- * @returns
- */
- public pop(path?: string,args?: any,cb?: Function){
- let canvas:Node = this.getCurentSceneRoot();
- let popUIs:Node = Utils.findName(canvas,this.popUIs);
- let isMain:boolean = Object.values(Constants.mainUIs).includes(path);
- let comp:any = null;
- if(Utils.isNull(path)){
- if(popUIs.children.length > 0){//关闭存在的popUIs最后一个节点
- let node: Node = popUIs.children.slice(-2)[0];
- node.parent = null;
- const scriptName = node.name.replace(/^\w/, (c) => c.toUpperCase());
- comp = node.getComponent(scriptName);
- }else{//返回主页面的上一层节点
- comp = this.getPageComponent(Constants.mainUIs.main);
- comp.tabBarIndex = comp.preIndexs.slice(-2)[0];
- }
- }else{
- const pageName: string = path.split('/').pop();
- const scriptName = pageName.replace(/^\w/, (c) => c.toUpperCase());
- if (!args) {args = [];}
- if(isMain){
- comp = this.getPageComponent(Constants.mainUIs.main);
- comp.tabBarIndex = comp.sceneNames.indexOf(path);
- popUIs.removeAllChildren();
- }else{
- let panel: Node = this.panels.get(path);
- let targetIndex = popUIs.children.findIndex(n => n.name == pageName);
- if (targetIndex !== -1) {
- popUIs.children.slice(targetIndex + 1).forEach(n => {
- n.parent = null;
- });
- popUIs.children.splice(targetIndex + 1);
- }
- panel.setSiblingIndex(panel.parent.children.length);
- comp = panel.getComponent(scriptName);
- }
- }
- if(comp && (comp as Component & PageActive)['pop']){
- (comp as Component & PageActive)['pop'].apply(comp, args);
- }
- if(typeof cb === 'function') {cb?.()};
- }
- /**
- * 直接关闭固定的名字中的一个页面
- * @param path Prefab的路径名称
- * @param cb 展示完成的回调函数
- * @returns
- */
- public hide(path: string,cb?: Function){
- if(!this.panels.has(path))return;
- let panel: Node = this.panels.get(path);
- const pageName: string = path.split('/').pop();
- const scriptName = pageName.replace(/^\w/, (c) => c.toUpperCase());
- let isMain = Object.values(Constants.mainUIs).includes(path);
- if(isMain){
- let container = Utils.findName(this.getCurentSceneRoot(),this.pageUIs);
- container.children.forEach((e:Node) => {
- e.setPosition(new Vec3((e.name == pageName ? 500000 : 0),0,1));
- });
- }else{
- panel.parent = null;
- const comp = panel.getComponent(scriptName);
- if(comp && (comp as Component & PageActive)['hide']){
- (comp as Component & PageActive)['hide'].apply(comp);
- }
- }
- if(typeof cb === 'function') {cb?.()};
- }
- /**
- * 从缓存页面中获取一个脚本
- * @param path 缓存的路径
- * @param scriptName 不传默认获取path名字最后一个字符串作为脚本的名字
- * @returns
- */
- public getPageComponent(path: string,scriptName?:string): any{
- if(!this.panels.has(path)){
- return null;
- }else{
- const sName = path.split('/').pop().replace(/^\w/, (c) => c.toUpperCase());
- let node: Node = this.panels.get(path);
- return node.getComponent(scriptName ?? sName);
- }
- }
- /**
- *从缓存页面中获取一个页面
- * @param path 缓存的路径
- */
- public getPageNode(path: string): Node{
- if(Utils.isNull(path))return null;
- if(!this.panels.has(path))return null;
- return this.panels.get(path);
- }
- /**
- * 在界面中显示的节点是否存在
- */
- public hasPageNode(path: string): boolean{
- if(Utils.isNull(path))return false;
- let name = path.split('/').pop();
- let canvas:Node = this.getCurentSceneRoot();
- let pages = Utils.findName(canvas,this.pageUIs);
- let popUIs = Utils.findName(canvas,this.popUIs);
- let nodes = pages.children.concat(popUIs.children)
- return nodes.some(e=>e.name == name);
- }
- /**
- * 得到当前场景的节点的根节点
- * @returns 根结点
- */
- public getCurentSceneRoot(): Node {
- return director.getScene().getChildByName('Canvas');
- }
- }
- //全局单例
- export const uiMgr = uiManager.ins();
|