首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当在UI元素外部发生点击时,如何关闭该元素?

当在UI元素外部发生点击时,如何关闭该元素?
EN

Stack Overflow用户
提问于 2020-12-07 18:01:53
回答 1查看 357关注 0票数 0

这个问题有很多解决方案,但似乎没有一个适合我。我有一个在UI元素中打开选择列表的按钮,我希望在它外部单击时关闭它。我目前有这个:

代码语言:javascript
运行
复制
private void OnEnable()
{
    EventSystem.current.SetSelectedGameObject(gameObject);
}

public void OnDeselect(BaseEventData eventData)
{
    //Close the Window on Deselect only if a click occurred outside this panel
    if (!mouseIsOver)
        gameObject.SetActive(false);
}

public void OnPointerEnter(PointerEventData eventData)
{
    mouseIsOver = true;
    EventSystem.current.SetSelectedGameObject(gameObject);
}

public void OnPointerExit(PointerEventData eventData)
{
    mouseIsOver = false;
    EventSystem.current.SetSelectedGameObject(gameObject);
}

它在PC上工作得很好,但不幸的是,由于移动设备上没有实际的指针,即使在里面点击,它也会关闭面板。我试过使用这样的东西:

代码语言:javascript
运行
复制
foreach (Touch touch in Input.touches)
    {
        int id = touch.fingerId;
        if (EventSystem.current.IsPointerOverGameObject(id))
        {
            isClicked = true;
        }
        if (Input.GetMouseButtonDown(0))
        {
            // Check if the mouse was clicked over a UI element
            if (EventSystem.current.IsPointerOverGameObject())
            {
                isClicked = true;
            }
        }
    }

但这也没有奏效。这似乎是一个令人难以置信的简单问题,我不明白为什么我找不到一个简单的解决方案。

EN

回答 1

Stack Overflow用户

发布于 2020-12-08 02:57:56

我建议在创建dropdown时使用Unity技术。

看看这个link

主要的想法是在你的按钮和其他ui元素后面创建拦截器。

你的开放面板函数应该看起来像这样:

代码语言:javascript
运行
复制
private RectTransform gameObjectTransform;
public void OpenPanel()
{
    CreateBlocker();
    gameObjectTransform = transform.parent;
    transform.SetParent(GetComponentInParent<Canvas>());
    transform.SetAsLastSibling();
}

创建拦截器方法,如文档中所示:

代码语言:javascript
运行
复制
private GameObject currentBlocker;
public void CreateBlocker()
{
    GameObject gameObject = new GameObject("Blocker");
    RectTransform rectTransform = gameObject.AddComponent<RectTransform>();
    rectTransform.SetParent(ChatGraphics.Instance.mainCanvas, false);
    rectTransform.anchorMin = (Vector2)Vector3.zero;
    rectTransform.anchorMax = (Vector2)Vector3.one;
    rectTransform.sizeDelta = Vector2.zero;
    Canvas canvas = gameObject.AddComponent<Canvas>();
    canvas.overrideSorting = true;
    canvas.sortingLayerID = component.sortingLayerID;
    canvas.sortingOrder = component.sortingOrder - 1;
    gameObject.AddComponent<GraphicRaycaster>();
    gameObject.AddComponent<Image>().color = Color.clear;
    gameObject.AddComponent<Button>().onClick.AddListener(delegate { Hide(); });
    currentBlocker = gameObject;
}

最后是Hide方法,它应该在每次都被调用(即使拦截器没有触发)

代码语言:javascript
运行
复制
public void Hide()
{
    if (currentBlocker != null)
        Destroy(currentBlocker);
    if (gameObjectTransform != null)
        transform.SetParent(gameObjectTransform);
    // Your code to hide your panel
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65179587

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档