I’m using ScrollView to add Labels at runtime. I want the new label to appear at the bottom of the list and the ScrollView to display the new label (currently ScrollView keeps focus on the first label).
Using scrollView.Add(newItem) places the label at the bottom, but I can’t for the life of me work out how to focus the ScrollView at the bottom of the list insead of the top.
A hack is to set the scrollOffset at the end of the frame.
scrollView.scrollOffset = new Vector2(0f, 2000000f);
Hi. I have a similar problem. Could someone give us an example how to force Scrollview constantly scroll to the bottom. Like a debug console. Thanks in advance.
Hello, you could wait for the label to be receive its layout (by register a callback for the GeometryChangedEvent and then use ScrollView.ScrollTo(label).
Ok. Let’s talk about ScrollView example below. This simple code adds a new text element as soon as a player types a command and presses Enter in the textfield.
However the scrollbar never reaches the bottom. Always ends up a few pixels above.
Use Label instead of TextElement. TextElement is a low level base class for many types of elements, including Button.
Avoid using a lambda for the GeometryChangedEvent registration so you can call “UnregisterCallback(yourFunc)” to immediately unregister this callback from your _lastItem element. Otherwise, all your _lastItem elements will constantly try to ScrollTo() themselves every time their Geometry changes (ie. width or height). This might explain the issue you’re having.
A simpler approach would be to just always scroll to the bottom of the ScrollView content. You can get the max offset from:
ScrollView sv;
var range = sv.verticalScroller.slider.range;
I’m trying to do this exact same thing… a “auto scroll to bottom” ScrollView.
This doesn’t work. When the Callback is called, the verticalScroller is exactly the same as it was at the point as the callback was registered. The only thing that is updated on the ScrollView is the contentConatiner (has the new dimensions). This can’t be used as the scroller won’t take a value higher than it thinks the highValue is.
The code that is not working (wrapping the label in a VisualElement as this will be more complicated in the future).
public void LogText(string pText)
{
VisualElement vi = new VisualElement();
Label label = new Label(pText);
label.AddToClassList("eLabelStandard");
vi.Add(label);
mSVLog.Add(vi);
vi.RegisterCallback<GeometryChangedEvent>(VIGeometryChangedCallback);
}
public void VIGeometryChangedCallback(GeometryChangedEvent evt)
{
((VisualElement)evt.target).UnregisterCallback<GeometryChangedEvent>(VIGeometryChangedCallBack);
mSVLog.verticalScroller.value = mSVLog.verticalScroller.highValue;
}
My work around for now is to do the “verticalScroller.value = verticalScroller.highValue” in the next Update() call, which is less than ideal but works…
Try registering the GeometryChangeEvent on the ScrollView’s contentContainer itself (in addition to adding it to your new item). The ScrollView uses the same event to update its verticalScroller min/max and your callback should be called after ScrollView’s callback (since you register it after it does).