Automatic Canvas size not working

Hello everyone. I’m having a problem with automatic canvas size and automatic size. The problem is automatic canvas (scrolling frame) doesn’t work when the child’s automatic size is enabled, the text label expands but when it reaches the end of the canvas, the canvas does not expand and the text label does not display the whole string. I’d really appreciate it if someone can tell me how to fix it

I also ran into this issue.


This is the workaround I’ve been using. Hopefully, Roblox will gain better support for automatic sizing/UI elements in the future.

Is there anyway to update it everytime the player types in something (its a textbox)

Yep, you can add this line with the other connections.
TextBoxLocation:GetPropertyChangedSignal("Text"):connect(function() UpdateSize(v,Layout) end)

If you’re strictly worried about size then you can use this instead of Text.
TextBoxLocation:GetPropertyChangedSignal("AbsoluteSize"):connect(function() UpdateSize(v,Layout) end)

it’s still not working? this is the script and the explorer

image


did I do it wrong?

Looks right. Are you changing the text and the ScrollingFrame has AutomaticCanvasSize enabled?

yes automaticcanvas is enabled but when I change the text, the canvas doesn’t expand

Hmm. I went ahead and tested it out with the same setup. It works for me.
Textbox Test

here is a video


it stops when the canvas is full and doesn’t expand

The textbox has AutomaticSize enabled?

yes it does
image
also textwrapped

did you use AbsoluteSize here?

TextWrapped is what is causing the issues if I had to guess. Textwrap cuts off any text that doesn’t fit within its bounds, thus not allowing AutomaticSize to trigger properly. Try it without text wrapping.

I disabled textwrapped and this happened,

edit: I also tried setting the frame’s scrolling direction to y only and it still doesn’t work

edit again: also in the developer wiki, it says that text wrapped should be enabled when automatic size is set to y

can you try recreating it again but with y scrolling instead of x?

Yeah. That’s correct. It should be that way but this is some weird behavior.
The issue is that with TextWrapped enabled, it will not allow AutomaticSize to be larger than its Parent AbsoluteSize.
This might need a custom solution/workaround. Lemme see if I can figure out one.

1 Like

I think I found the problem. Your code is actually expanding the scrolling frame’s Y offset canvas size, but the text box is using scale, so I tried it with TextWrapped enabled and then changed something in the code.

so it would edit the offset instead,

then I tried it and this happened

the canvas expands too much, as you can see in the scroll bar (maybe because offset and scale works differently, so it should expand to the perfect size with the right formula)

but another problem showed up, it’s that the text box also stopped when it reached the size of the original canvas. the canvas was still expanding when i’m typing more texts, but the text box automatic size doesn’t work

edit: I changed these from offset to scale

image

edit again: it’s still doing the same thing (expanding too big)

Yeah, the canvas is supposed to work like that. The AutomaticCanvasSize should have its Offset the same as it’s content AbsoluteSize. It’s set to Offset instead of Scale for a reason. The only time you should use scale is when trying to multiply how much bigger you want it to be. The padding variables are used to account UIPadding Offsets. Because I was just using it as a personal workaround and wasn’t using UIPadding Scale, I didn’t include anything for UIPadding Scale.

You noted that the text box also stopped when it reached the size of the original canvas. That’s not why its doing that. Like I said previously,

Its dependent on it’s Parent AbsoluteSize not AbsoluteCanvasSize.

So do I need to do the textbox sizing manually?

Here is the workaround I conjured up. This isn’t perfect (it can miss fast typed text) but I hope that it will suffice.

You’ll need to make sure that TextWrapped is disabled, this “should” do the text wrapping for you since Roblox’s own TextWrapping doesn’t work properly with AutomaticSize. If this doesn’t work, I don’t know if I can come up with anything better.

local function UpdateSize(FrameInstance,LayoutInstance)
	if FrameInstance and LayoutInstance then
		local PaddingX = 0
		local PaddingY = 0
		if FrameInstance:FindFirstChildOfClass("UIPadding") then
			local UIPadding = FrameInstance:FindFirstChildOfClass("UIPadding")
			PaddingX += UIPadding.PaddingLeft.Offset
			PaddingX += UIPadding.PaddingRight.Offset
			PaddingY += UIPadding.PaddingBottom.Offset
			PaddingY += UIPadding.PaddingTop.Offset
		end
		if FrameInstance.AutomaticCanvasSize == Enum.AutomaticSize.Y then
			FrameInstance.CanvasSize = UDim2.new(0,0,0,LayoutInstance.AbsoluteContentSize.Y + PaddingY)
		elseif FrameInstance.AutomaticCanvasSize == Enum.AutomaticSize.X then
			FrameInstance.CanvasSize = UDim2.new(0,LayoutInstance.AbsoluteContentSize.X + PaddingX,0,0)
		elseif FrameInstance.AutomaticCanvasSize == Enum.AutomaticSize.XY then
			FrameInstance.CanvasSize = UDim2.new(0,LayoutInstance.AbsoluteContentSize.X + PaddingX,0,LayoutInstance.AbsoluteContentSize.Y + PaddingY)
		end
	end
end


local v = script.Parent
local Layout = v:FindFirstChildOfClass("UIListLayout") or v:FindFirstChildOfClass("UIGridLayout")
local TextBox = script.Parent.TextBox
TextBox:GetPropertyChangedSignal("AbsoluteSize"):connect(function() UpdateSize(v,Layout) end)
local LastAdjustedAWholeWord = ""
TextBox:GetPropertyChangedSignal("TextFits"):Connect(function()
	local LP = game.Players.LocalPlayer
	if TextBox.TextFits == false then
		local OldText = TextBox.Text
		local TextAdjustment = 1
		TextBox.TextEditable = false
		TextBox:ReleaseFocus()
		repeat
			local RevString = string.reverse(TextBox.Text)
			local NewString = ""
			if RevString:find(" [%C]") and (RevString:sub(1, RevString:find(" [%C]", TextAdjustment)):find(LastAdjustedAWholeWord) == nil or LastAdjustedAWholeWord == "") then
				LastAdjustedAWholeWord = RevString:sub(1, RevString:find(" [%C]", TextAdjustment))
				NewString = RevString:sub(1, RevString:find(" [%C]", TextAdjustment)) .."\n" ..  RevString:sub(RevString:find(" [%C]", TextAdjustment)+1, RevString:len())
			else
				NewString = RevString:sub(1, RevString:find("%C", TextAdjustment)) .."\n" ..  RevString:sub(RevString:find("%C", TextAdjustment)+1, RevString:len())
			end
			TextBox.Text = string.reverse(NewString)
			TextAdjustment+=1
			wait()
		until TextBox.TextFits == true
		TextBox.TextEditable = true
		TextBox:CaptureFocus()
	end
end)

This might behave weird or improperly when pasting long texts and/or typing fast. Like I said this is a workaround, not a solution. Roblox needs to fix their Gui problems on their own. It’s been lacking proper support for years, they add new features but don’t adapt the rest of it to be properly compatible. Still waiting on Roblox for proper rotation support (Antialiasing, AnchorPoints that respect rotation, etc.) :weary: