Cocos Creator 踩坑 - Toggle Group 与 Toggle Container

要用 Toggle Container, Toggle Group 有些问题

前言

因为踩了这个坑,所以也特意补发了一章 关于 Toggle 的文章

回归正文。

ToggleGroup/ToggleContainer 不是一个可见的 UI 组件,它可以用来修改一组 Toggle 组件的行为。
当一组 Toggle 属于同一个 ToggleGroup/ToggleContainer 的时候,就只能有一个 Toggle 处于选中状态。

注意:ToggleGroupToggleContainer 不同之处在于,使用 ToggleContainer 所有包含 Toggle 组件的一级子节点都会自动被添加到该容器中,而 ToggleGroup 需要手动进行 Toggle 组件的绑定。

ToggleGroup/ToggleContainer 组件

TC
TG

点击 属性检查器 下面的 添加组件 按钮,然后选择 UI组件 中的 ToggleGroup/ToggleContainer,即可添加至节点。

也可以在 层级管理器面板上,右键->创建节点->创建UI节点->ToggleGroup/ToggleContainer 添加。

想要查看 ToggleGroup 的API,请点击这里,想要查看 ToggleContainer 的API,请点击这里

因为 ToggleGroup 和 ToggleContainer就是新版与旧版,所以就直接一起列出。
·
·
·

ToggleGroup 和 ToggleContainer 的属性

属性(properties) 说明
allowSwitchOff Boolean 设置为 true, 那么 Toggle 按钮在被点击的时候可以反复地被选中和取消选中。
toggleItems Toggle[] 只读属性,返回 ToggleGroup/ToggleContainer 管理的 Toggle 数组引用。
checkEventsComponent.EventHandler[] Toggle 按钮的点击事件列表。(只有 ToggleContainer含有)

重点! 踩坑了。

这个是我 Toggle 组的初始化,给组内每个Toggle 进行监听绑定


ToggleMgr.js ==>	cc.Class({
	    extends: cc.Component,
	    properties: { power: [cc.Toggle], _power:[] },
	    onLoad () {
	    	this._power = ["100-120","90-140","110-130","80-150"];
			this.AddListener( this.power, this._power , "PowerChanged" );
	    },
	
		AddListener: function( toggles, datas, func ) {
			if( toggles ){
				let length = toggles.length;
				let _length = this.datas.length;
				for(let i= 0; i< length; i++){
					if(i<_length){
						let check = new cc.Component.EventHandler();// 创建一个新的事件处理
						check.target = this.node;                  	// 绑定回调方法所在的节点
						check.component = "ToggleMgr";             	// 绑定回调方法所在的脚本名字
						check.handler = func;           			// 绑定的回调方法的名字
						check.customEventData = this.datas[i];   	// 绑定的回调方法的参数
						this.toggles[i].checkEvents = [];			// 清空 toggle 回调事件列表
						this.toggles[i].checkEvents.push(check); 	// 将方法绑定到指定 toggle
					}
				}
			}
		}
		
	    PowerChanged: function(toggle, customEventData) {
	    	if(toggle.isChecked) console.log("You choose ",customEventData);
	    },
	});
	

一开始我以为 ToggleGroupToggleContainer 的区别在于:ToggleGroup 需要手动绑定Toggle,很繁琐。
还有就是 ToggleContainer 可以直接在本身的 checkEvents中进行子Toggle的监听绑定。

其实差别也不是非常大,但是在公司的项目中却出现了个问题。

有一组 Toggle 绑定的方法是相同的,但却发现每当父节点隐藏起来 ,子 Toggle 就会遍历触发一次 isChecked = true,也就是执行监听回调方法。

而且开始遍历的下标也跟自己所选中的 Toggle 有关系。

倍数

比如说 我有一组 Toggle(4个倍数),对应的CustomEventData 分别是[ “x1”“x3”“x5”“x10”]。

当我选择值为 “x1”Toggle 时,遍历就从值为 “x3” 开始调用监听回调,一直到结束。以此类推。

那怎么办呢,开始找BUG吧。相关代码仔细查找了一番,发现代码是没有问题的。

那就看看 Toggle 组件是否有问题吧,新建场景,绑定一个只有打印的监听回调方法,将它隐藏/显示切换。

emmmm,没问题。那就看看 ToggleGroup 吧,同样的步骤,将它隐藏/显示切换。

诶!! 问题出现了。

ToggleGroup 在节点隐藏的时候,会导致以当先选中下标为开始遍历调用子节点 Toggle 组件。

	也就是说选择 "x1" ,隐藏时自动遍历选择 "x3","x5","x10" 然后结束遍历调用。
		    选择 "x3" ,隐藏时自动遍历选择 "x5","x10" 然后结束遍历调用。
		    选择 "x5" ,隐藏时自动遍历选择 "x10" 然后结束遍历调用。

尝试一下使用 ToggleContainer 来替换 ToggleGroup 组件,显示/隐藏一下,没有出现同样的问题。

看来就是 ToggleGroup 的自执行调用方式产生了某些BUG,导致他在关闭的时候会遍历子Toggle执行。

至于具体原因 我也某度了一下。查了很多篇文章,但是也没有人反映过这个问题。

问题已留在心里,适当时机可能就会解决。不过目前既然有了 ToggleContainer 来替换 ToggleGroup

就没必要花费太多时间去纠结这个问题,等什么时候空闲下来,再去好好了解一下。

猜你喜欢

转载自blog.csdn.net/qq_38269366/article/details/89032856