Function for automatically scaling scrolling frames

I’ve tried countless things, I cannot for the life of me figure out how to do this: scale a scrolling frame to adapt when new items are added into it, I want the items to keep their original size but the scrolling frame will be able to scroll down to the bottom how many frames or whatever is added there are.

TLDR: function to automatically scale a scrolling frame based on new frames being added, keep frames Y size (IN SCALE, NO OFFSET) so that it doesn’t cut off scrolling ability after a few frames and goes all the way down.

I don’t have any current code since I scrapped it all. If anyone can help me, it would be greatly appreciated.

1 Like

I have this that I used for UIListLayouts

local function ScaleScroll(scroller: ScrollingFrame)
	local Layout: UIListLayout? = scroller:FindFirstChildWhichIsA("UIListLayout")
	local UIPadding: UIPadding? = scroller:FindFirstChildWhichIsA("UIPadding")

	local TotalYSize = 0
	local Padding = 0
	local PaddingOffsetTop = 0
	local PaddingOffsetBottom = 0

	if Layout then
		Padding = Layout.Padding.Scale
	end

	if UIPadding then
		PaddingOffsetTop = UIPadding.PaddingTop.Offset
		PaddingOffsetBottom = UIPadding.PaddingBottom.Offset
	end

	for _, v in pairs(scroller:GetChildren()) do
		if v:IsA("Frame") or v:IsA("TextButton") or v:IsA("ImageButton") or v:IsA("ScrollingFrame") or v:IsA("ImageLabel") or v:IsA("VideoFrame") or v:IsA("ViewportFrame") or v:IsA("TextLabel") then
			TotalYSize += v.Size.Y.Scale
			TotalYSize += Padding
		end
	end

	scroller.CanvasSize = UDim2.new(0, 0, TotalYSize, (PaddingOffsetTop + PaddingOffsetBottom))
end
1 Like

Will it also work for UI grid layouts? If not it’s alright.Do you run it after all the frames are in or after each frame is in (I’m using a for loop to add frames to the container)

Thanks for the response!

2 Likes

I’m going to try this out, I’ll get back to you if I have any issues.

1 Like

So unfortunately, this did not work. The frames have gotten larger, (which I don’t think is correct) and I can only scroll past a few frames. Do you know what could be causing this?

1 Like
local frame: ScrollingFrame = game.Players.LocalPlayer:WaitForChild("PlayerGui"):WaitForChild("ScreenGui").ScrollingFrame -- ScrollingFrame
local grid = frame:WaitForChild("UIGridLayout") -- UIGridLayout

frame.CanvasSize = UDim2.new(0, 0, 0, grid.AbsoluteContentSize.Y+15)

frame.ChildAdded:Connect(function(_)
	frame.CanvasSize = UDim2.new(0, 0, 0, grid.AbsoluteContentSize.Y+15)
end)

Try this code

1 Like

Trying it out now, thanks for the response.

2 Likes

Sadly, this also did not work. It’s just making the size of the frames extremely large, and I can only scroll past a few. Any ideas why?

1 Like

I made a function out of that, if this helps.

function ScrollScale(ScrollingFrame: ScrollingFrame)
	local Grid = ScrollingFrame:FindFirstChildWhichIsA("UIGridLayout")
	ScrollingFrame.CanvasSize = UDim2.new(0, 0, 0, Grid.AbsoluteContentSize.Y+15)
end

I’m using a UIGridLayout, and its size is using frame too, not offset.

1 Like

It happens because you need to calculate scale of frames you adding (I’ll rewrite the code for you)

2 Likes
local frame: ScrollingFrame = game.Players.LocalPlayer:WaitForChild("PlayerGui"):WaitForChild("ScreenGui").ScrollingFrame
local grid: UIGridLayout = frame:FindFirstChildWhichIsA("UIGridLayout")
local default_size = 100 -- size in pixels of frames in the scrolling frame

frame.ChildAdded:Connect(function(_)
	frame.CanvasSize = UDim2.new(0, 0, 0, grid.AbsoluteContentSize.Y+15)
	for _,v: Frame in ipairs(frame:GetChildren()) do
		if v.ClassName ~= "UIGridLayout" then
			grid.CellSize = UDim2.new(grid.CellSize.X, UDim.new(default_size / frame.AbsoluteCanvasSize.Y, 0))
		end
	end
end)
1 Like

I’ll try this out soon, thanks for the help. I’ll let you know.

2 Likes

Should the default size be the Y Scale value of the frame being added?

1 Like

The Y AbsoluteSize value of the frame being added

1 Like

Alright… It’s still not working for some reason. Do you need any other details for the debugging?

function ScrollScale(ScrollingFrame: ScrollingFrame)
	local Grid: UIGridLayout? = ScrollingFrame:FindFirstChildWhichIsA("UIGridLayout")
	local DefaultSize = script.Template.AbsoluteSize.Y
	
	ScrollingFrame.CanvasSize = UDim2.new(0, 0, 0, Grid.AbsoluteContentSize.Y+15)
	for _,v: Frame in ipairs(ScrollingFrame:GetChildren()) do
		if v.ClassName ~= "UIGridLayout" then
			Grid.CellSize = UDim2.new(Grid.CellSize.X, UDim.new(DefaultSize / ScrollingFrame.AbsoluteCanvasSize.Y, 0))
		end
	end
end
1 Like

What is the value of the Size.Y of the frame being added?

I might have found the issue, give me a second to look into it.

2 Likes

image

When I print the cell size of the layout, after every iteration in the loop this is the result:
{0.949999988, 0}, {0, 0}

If there’s really no way to do it using a GridLayout, I can switch to a list layout if needed.

UIGridLayout.CellSize.Y.Scale * ScrollingFrame.AbsoluteCanvasSize.Y