要用 Toggle Container, Toggle Group 有些问题
前言
因为踩了这个坑,所以也特意补发了一章 关于 Toggle
的文章
回归正文。
ToggleGroup/ToggleContainer
不是一个可见的 UI
组件,它可以用来修改一组 Toggle
组件的行为。
当一组 Toggle 属于同一个 ToggleGroup/ToggleContainer
的时候,就只能有一个 Toggle
处于选中状态。
注意:ToggleGroup
与 ToggleContainer
不同之处在于,使用 ToggleContainer
所有包含 Toggle
组件的一级子节点都会自动被添加到该容器中,而 ToggleGroup
需要手动进行 Toggle
组件的绑定。
ToggleGroup/ToggleContainer 组件
点击 属性检查器 下面的 添加组件
按钮,然后选择 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);
},
});
一开始我以为 ToggleGroup
与 ToggleContainer
的区别在于: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
。
就没必要花费太多时间去纠结这个问题,等什么时候空闲下来,再去好好了解一下。