Wrong position when re-instantiating a pooled UI object

I have a a UI object, which is a dialog window with a Panel as a parent UI element. I have created a prefab for this game object. I also have implemented pooling logic so that I am reusing instances of this dialog within the game, instead of always instantiating a new object.

I also have single game object on the scene, where I have created a Canvas element to host any UI elements I need to display. My goal is to be able to instantiate the dialog into the canvas, and as the dialog’s rect transform is set to expand to the edges of its container, I expect it to appear “fullscreeen”.
Here is the code I am using:

Transform dialogTransform = FindPooledInstance(dialogPrefab).transform;
if (!dialogTransform)
    dialogTranform = Object.Instantiate(dialogPrefab, globalCanvas.gameObject).transform;
    dialogTranform.SetParent(globalCanvas, false);

In the above code, globalCanvas is a RectTransform referring to my global canvas object, and dialogPrefab is a GameObject field referring to the prefab I have created for my dialog.

Everything works fine when there is no pooled instance (we enter the if- clause) – the dialog object is created and placed exactly as I expect it. The problem occurs when I am showing the dialog again, when it gets recovered from the object pool (in the else-clause) – its position is being changed and it appears partially (or sometimes fully) off-screen.

In other places in my logic, I use the following code to “return” an existing dialog back to the pool:

dialogTransform.SetParent(pool, false);

Here, pool is a Transform (not a RectTransform) somewhere in my scene, where I am placing unused pooled objects. I guess the way I do the “return to pool” logic could be causing the problem, but I fail to recognize exactly what I am doing wrong.

Any advice would be appreciated.

I am using Unity 2017.4.

The dialog is getting repositioned and rescaled due to SetParent(..., false). It is really confusing when to use false and true for the second parameter (I always get it wrong on the first try). Try using true in both locations, or only when moving it to the pool. Or you could just use transform.parent property.

Optionally, you could also just call gameObject.SetActive(false) on it and not move it to the pool, then SetActive(true) when you need it again.

It’s really confusing, why are you even pooling UI object, instead of set them active to true or false when needed?
I don’t think this amount of code is enough to solve this your way.