I got it working. For anyone with the same problem, here is what I did:
In UIPanel, replace CalculateConstrainOffset with
public virtual Vector3 CalculateConstrainOffset (Vector2 min, Vector2 max, bool SnapToTopOfGrid = false)
{
Vector4 cr = finalClipRegion;
float offsetX = cr.z * 0.5f;
float offsetY = cr.w * 0.5f;
Vector2 minRect
= new Vector2
(min
.x, min
.y); Vector2 maxRect
= new Vector2
(max
.x, max
.y);
Vector2 minArea
= new Vector2
(cr
.x - offsetX, cr
.y - offsetY
); Vector2 maxArea
= new Vector2
(cr
.x + offsetX, cr
.y + offsetY
);
if(SnapToTopOfGrid)
{
UIGrid ChildGrid = GetComponentInChildren<UIGrid>();
if(ChildGrid != null)
{
BetterList<Transform> childs = ChildGrid.GetChildList();
UIWidget lastChildWidget = childs[childs.size-1].GetComponent<UIWidget>();
float childHeight = lastChildWidget.CalculateBounds().extents.y;
float newExtentY = -cr.w;
newExtentY+=childHeight;
if(newExtentY < minRect.y)
{
minRect.y = newExtentY;
}
}
}
if (clipping == UIDrawCall.Clipping.SoftClip)
{
minArea.x += clipSoftness.x;
minArea.y += clipSoftness.y;
maxArea.x -= clipSoftness.x;
maxArea.y -= clipSoftness.y;
}
return NGUIMath.ConstrainRect(minRect, maxRect, minArea, maxArea);
}
then in UIScrollView, add "true" as a paramater to both the "CalculateConstrainOffset" method calls, ie:
Vector3 constraint = mPanel.CalculateConstrainOffset(bounds.min, bounds.max);
//becomes
Vector3 constraint = mPanel.CalculateConstrainOffset(bounds.min, bounds.max, true);
Things to be aware of:
Only tested to on UIScrollView that scroll vertically and snap to the top.
Expects a UIGrid child which contains a vertical grid of items of the same height.