UGUI之ScrollRect添加响应事件后不能滑动

来源:互联网 发布:网络通信运营商 编辑:程序博客网 时间:2024/05/16 11:51

今天发现个问题UGUI的ScrollRect组件会和放在它上面的button或者toggle等组件有事件响应的冲突,具体体现为上面的组件会遮挡下面的响应,button或者toggle等组件上出现只能点击不能滑动的效果要想滑动必须点旁边才行。这样的用户体验是绝对不可以的,所以必须解决掉!

具体实例:

下面是项目中要送礼物的列表,我的GiftImage是整个黑色的背景,同时上面加了ScrollRect和toggle group(也就是ScrollRect)。因为Grid下面我用的都是Toggle。但是我用的是一个框架中的OnClick事件来响应Toggle的点击事件(和button的OnClick事件类似)。所以当鼠标和手指放到图片(也就是toggle)上时是不能实现滑动效果的。因为被toggle挡住了响应事件。



那么如何解决:网上大多资料说的都是button与ScrollRect的冲突而不是toggle。于是我把我的toggle换成了button做测试。----结果是网上的说法可以解决,具体如下:

把下面第一句代码放到start()里调用下面代码的方法就可以了(详细解释看下面):

第一句代码中的UIinit.flowergift是一个button(我这里是框架方法,实际就是一个button),然后直接用监听调用下面,最后可以解决与ScrollRect的冲突,也就是说既可以点击button实现点击功能又可以滑动。


 UIinit.flowergift.onClick.AddListener(delegate () { choosegiftflower(UIinit.flowergift.gameObject); }); public void choosegiftflower(GameObject go)//花    {        //安卓选择花朵方法               mSelectedGiftIndex = 1;        matchgifts = allgiftslist[1];//本地图片和id匹配        Debug.Log("flower" + matchgifts.name);        // Debug.Log();    }


button与ScrollRect的冲突解决了。下面看Toggle的了,我试了几次框架中方法(也就是用toggle来使用OnClick方法,在我的框架里是可行的,但是放到这个冲突里就不能用了)不可行最后只能放弃框架的用了isOn的方法。

把下面第一段代码放到update里,然后调用下面的方法,一样是可以解决与ScrollRect的冲突,也就是说既可以点击Toggle进行选择又可以滑动。


if (UIinit.flowergift != null)//花         {             if (UIinit.flowergift.isOn)             {                 choosegiftflower();             }                     }  

public void choosegiftflower()//花      {          //安卓选择花朵方法                    mSelectedGiftIndex = 1;          matchgifts = allgiftslist[1];//本地图片和id匹配          Debug.Log("flower" + matchgifts.name);                }  


-----------------------------------------------------------------------------------------------------------------------------------------


今天后补一下我上面项目中那个ison的方法有时并不灵敏,应该是我项目里有其他的代码干扰。但这个方法确实可行,为此我又做了测试:

在这个测试项目里,我直接有四个toggle做成一个group放到grid里(和上个项目一样),image是一个滑动的列表,如下图2,同时添加一个mask;之后给canvas加一个脚本测试:

图2:

添加脚本测试:

using UnityEngine;using System.Collections;using UnityEngine.UI;public class testtoggle : MonoBehaviour{    public GameObject[] fourtoggel;     void Update()    {        if (fourtoggel[0].GetComponent<Toggle>().isOn == true)        {            Debug.Log("出现log1");        }        if (fourtoggel[1].GetComponent<Toggle>().isOn == true)        {            Debug.Log("出现log2");        }        if (fourtoggel[2].GetComponent<Toggle>().isOn == true)        {            Debug.Log("出现log3");        }        if (fourtoggel[3].GetComponent<Toggle>().isOn == true)        {            Debug.Log("出现log4");        }    }}

最后log结果:


所以这个方法是可行的。但如果项目其他代码会对这里进行干扰建议使用button的方法。上述button的onclick方法没有任何问题。只是如果要有toggle的选中的对勾标志就得手动再去写代码了。

------------------------------------------关于button和toggle以及ScrollRect之间的冲突完毕---------------------------------------

下面讲关于手动写选中标志方法:

在我项目里,每个礼物都是一个button,都有一个对号标志的黄颜色图片,我给Grid里加一个脚本,对应把每个礼物旁边的黄颜色对号图片对应放进去(要按顺序放,顺序跟下面代码的顺序有关,为了方便建议依次放入)。


然后看看grid上的脚本:

using UnityEngine;using System.Collections;public class Showchoice : MonoBehaviour {    public GameObject[] choices_ofbuttons;//多少个按钮的就有多少个选项      public int show_numburs;    // Use this for initialization    public void selectshow()    {        switch (show_numburs)        {            case 0:                showed(show_numburs);                break;            case 1:                showed(show_numburs);                break;            case 2:                showed(show_numburs);                break;            case 3:                showed(show_numburs);                break;            case 4:                showed(show_numburs);                break;            case 5:                showed(show_numburs);                break;            case 6:                showed(show_numburs);                break;            case 7:                showed(show_numburs);                break;        }    }    private void showed(int j)    {        choices_ofbuttons[0].SetActive(false);        choices_ofbuttons[1].SetActive(false);        choices_ofbuttons[2].SetActive(false);        choices_ofbuttons[3].SetActive(false);        choices_ofbuttons[4].SetActive(false);        choices_ofbuttons[5].SetActive(false);        choices_ofbuttons[6].SetActive(false);        choices_ofbuttons[7].SetActive(false);        choices_ofbuttons[j].SetActive(true);  //首先将所有的都置为false然后把传入的按个设置为真    }    void Start () {        choices_ofbuttons[0].SetActive(false);        choices_ofbuttons[1].SetActive(false);        choices_ofbuttons[2].SetActive(false);        choices_ofbuttons[3].SetActive(false);        choices_ofbuttons[4].SetActive(false);        choices_ofbuttons[5].SetActive(false);        choices_ofbuttons[6].SetActive(false);        choices_ofbuttons[7].SetActive(false);    }// Update is called once per framevoid Update () {}}

上述方法的思路就是在start()里面让所以图标都不显示,然后选择了哪个就让哪个显示同时让其他的都重新不显示。这样就搞定了显示的方法!只要在调用这个代码的时候给show_numburs赋值和调用selectshow()就OK。每个button都赋值不同并且调用。如下:


这样就搞定了所有了!!!

0 0
原创粉丝点击