I am releasing this on the forums as I have previously uploaded a module that achieved something similar, and a lot of people have found that useful. So consider this version 2 of that module.
After struggling with the new AutoSize and AutoCanvasSize properties of GuiObjects for a while (they are a great addition to the engine and work fantastic, most of the time), I decided to create a module to handle this for me with some added utility. It’s nothing impressive but I find it handy.
AutoSize allows automatic resizing of Frame (.Size) and ScrollingFrame (.CanvasSize) objects. The object being resized must have a UIListLayout or UIGridLayout as a direct child to work properly.
Supports tweening on update if you’d like, you can make some smooth effects with this.
Usage:
-- frame is a Frame or ScrollingFrame GuiObject to resize
-- axes is a table which includes "X", "Y", or both. Excluded axes will be ignored during resizing. defaults to {"X", "Y"}.
-- tweenSettings is a dictionary that controls tweening on update. defaults to nil (no tweening)
-- duration = tween duration, direction = Enum.EasingDirection, style = Enum.EasingStyle
AutoSize.Connect(frame, axes, tweenSettings)
-- to stop autosizing, call .Disconnect, passing the frame.
-- the module does not cleanup based on ancestry changed events, so you'll need to do this if you're adding/removing size-able frames at runtime, or you'll have a memory leak.
AutoSize.Disconnect(frame)
AutoSize Module code
local Tween = require(script:WaitForChild("Tween"))
local DEFAULT_TWEEN_SETTINGS = {
duration = .5;
style = Enum.EasingStyle.Quint;
direction = Enum.EasingDirection.Out;
}
local listening = {}
local AutoSize = {}
function AutoSize.Update(frame)
local entry = listening[frame]
if entry then
local layout = frame:FindFirstChildWhichIsA("UIListLayout") or frame:FindFirstChildWhichIsA("UIGridLayout")
if layout then
local property = frame:IsA("ScrollingFrame") and "CanvasSize" or "Size"
local currentSize = frame[property]
local contentSize = layout.AbsoluteContentSize
local sizeX = table.find(entry.axes, "X") and contentSize.X or currentSize.X.Offset
local sizeY = table.find(entry.axes, "Y") and contentSize.Y or currentSize.Y.Offset
local size = UDim2.new(currentSize.X.Scale,sizeX,currentSize.Y.Scale, sizeY)
if entry.tweenSettings then
Tween(frame, {[property] = size;}, entry.tweenSettings.duration or DEFAULT_TWEEN_SETTINGS.duration, entry.tweenSettings.style or DEFAULT_TWEEN_SETTINGS.style, entry.tweenSettings.direction or DEFAULT_TWEEN_SETTINGS.direction)
else
frame[property] = size
end
end
end
end
function AutoSize.Connect(frame, axes, tweenSettings)
if not listening[frame] then
local layout = frame:FindFirstChildWhichIsA("UIListLayout") or frame:FindFirstChildWhichIsA("UIGridLayout")
if layout then
local entry = {
connections = {
layout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function()
AutoSize.Update(frame)
end);
};
tweenSettings = tweenSettings;
axes = axes or {"X";"Y"};
};
listening[frame] = entry
return entry
end
end
end
function AutoSize.Disconnect(frame)
local entry = listening[frame]
if entry then
for _,c in pairs(entry.connections) do
c:Disconnect()
end
listening[frame] = nil
end
end
return AutoSize
Additional Tween utility module code, which is used in AutoSize
local TweenService = game:GetService("TweenService")
local Tween = {}
function Tween.Make(instance, tweenInfo, properties)
tweenInfo = tweenInfo or TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut)
local tween = TweenService:Create(instance, tweenInfo, properties)
return tween
end
function Tween.Do(instance, properties, duration, style, direction, yieldUntilFinished)
local tweenInfo = TweenInfo.new(duration, style, direction)
local tween = Tween.Make(instance, tweenInfo, properties)
tween:Play()
if yieldUntilFinished then
return tween, tween.Completed:Wait()
end
return tween
end
return Tween.Do
or get it on the website: AutoSize Module - Roblox