I’ve found an issue where UIPageLayout’s PageEnter event does not always fire when navigation methods are triggered quickly in opposite directions.
This happens when Next() is called and, almost immediately afterward, Previous() is called (for example, due to a fast double-click or overlapping UI interactions). The UIPageLayout does visually change pages correctly, but the PageEnter signal fails to fire for the final page.
Expected Behavior
Each time the displayed page changes — regardless of how quickly or in which direction — the PageEnter event should fire for the newly active page.
Actual Behavior
When Next() is immediately followed by Previous() (or vice-versa):
The page changes correctly on-screen
But PageEnter never fires for the second transition
Only the first PageEnter event fires
This causes logic tied to PageEnter (e.g., setup, validation, animations, UI state updates) to fail.
local gui = script.Parent
local pageLayout = gui:FindFirstChildWhichIsA("UIPageLayout")
local lastEntered
if not pageLayout then
warn("No UIPageLayout found in parent!")
return
end
-- Wait so you can see the starting page
task.wait(1)
warn("PAGELAYOUT TEST: Starting test...")
warn("Inital page name:", pageLayout.CurrentPage.Name)
-- Print when entering a page
pageLayout.PageEnter:Connect(function(page)
warn("PageEnter fired for:", page.Name)
lastEntered = page
end)
-- Trigger the bug: call Next() then Previous() immediately
pageLayout:Next()
task.wait(0.1)
pageLayout:Previous()
warn("PAGELAYOUT TEST: Test executed: Expected 2 PageEnter events")
warn("CURRENT PAGE:", pageLayout.CurrentPage.Name)
warn("LAST ENTERED:", lastEntered.Name)
Hi Vinny, it is expected behavior for PageEnter to fire only when the page has come back into view and is about to be rendered per the official documentation.
PageEnter
Fires when a page comes into view, and is going to be rendered.
In your example, since the pages are being swapped so rapidly, the original page never goes out of view. Consequently, when returning to that page, it will not come back into view because it has always been in view.
I understand it may be confusing to tie these signals to rendering. I would recommend instead connecting a property changed signal to CurrentPage if you are simply trying run logic when Previous(), Next(), and JumpTo() update the current page. Let me know if this workaround works for you!