IsPointerOverGameObject doesn't work on TouchPhase.Ended?

I have an AR game where clicking on the screen spawns a GameObject at the touch position, but I don’t want to spawn an object when the user clicks one of the UI buttons I have set up. I ended up using EventSystem.IsPointerOverGameObject. This didn’t seem to work though, and even after passing the touch’s fingerID, the object still spawned on mobile. My code looked like this:

if (Input.touchCount)
{
	Touch touch = Input.GetTouch (0);
	if (touch.phase == TouchPhase.Ended && !EventSystem.current.IsPointerOverGameObject (touch.fingerId)) {
		SpawnObject (touch.position);
	}
}

None of the solutions I found online were able to fix this. However, when I tried debugging by printing IsPointerOverGameObject to the screen and clicking a UI element, I noticed it would be a string of trues followed by a false. This led me to realize the problem wasn’t IsPointerOverGameObject, but rather TouchPhase.Ended. With this small change, my code works perfectly:

if (Input.touchCount)
{
	Touch touch = Input.GetTouch (0);
	if (touch.phase == TouchPhase.Began && !EventSystem.current.IsPointerOverGameObject (touch.fingerId)) {
		SpawnObject (touch.position);
	}
}

So my question is this: why doesn’t TouchPhase.Ended work the same as TouchPhase.Began? Is this expected behavior and I’m just missing something, or a bug?

Thank you!

if you are using UI buttons then for sure you are also using UI panels also … so i would advice you to stop using Touch api and simply attach an EventTrigger on UI panel that is beneath your UI buttons and then Add a new Event Type from its Supported Event Types (preferably PointerClick) and then the rest is same as calling a function on button click … the function you will call from this new PointerClick can now fetch the Touch Position

Accept if it worked for you ^^