Sizing and safe areas

Learn how SkeleKit measures and arranges views without Auto Layout constraints.

SkeleKit uses a two-pass layout system. A parent first asks each child how much space it wants, then assigns its final bounds. There is no Auto Layout constraint graph to maintain.

The built-in containers apply that system in different ways; start with StackPanel and Grid for the common cases.

Requested and constrained sizes

Width and Height request explicit dimensions. Leave them unset to use the size measured from content. MinWidth, MaxWidth, MinHeight, and MaxHeight constrain either result.

new Button
{
    HorizontalAlignment = HorizontalAlignment.Stretch,
    MinHeight = 44,
    MaxWidth = 420,
    Margin = new Thickness(16, 8),
    Text = "Continue"
};

Margin belongs to every View and reserves space outside it. Padding belongs to panels and reserves space between the panel's bounds and its children.

Alignment

Horizontal and vertical alignment decide where a view sits when its parent offers more room than it needs.

  • Start, Center, and End keep the measured size and position it along that axis.
  • Stretch uses the available size, subject to minimum and maximum constraints.

An explicit size still takes precedence over stretching. Layout containers may apply additional rules; for example, a vertical StackPanel stacks measured heights but still controls the horizontal slot.

Measurement state

After measurement, DesiredSize contains the requested size. After arrangement, ArrangedBounds contains the final position and size in the parent.

Normal property setters invalidate layout automatically. Call InvalidateMeasure() after changing custom state that affects a custom view's desired size. InvalidateSubtree() is intended for changes that invalidate every descendant, such as a typography environment change.

LayoutNow() forces a pending pass from the root. It is rarely needed in application code, but can be useful before reading final bounds for an immediate native operation.

Geometry values

SkeleKit uses its own small value types throughout layout:

  • Size stores width and height.
  • Point stores an x and y coordinate.
  • Rect combines an origin and size.
  • Thickness stores left, top, right, and bottom insets.

They support the usual constructors and helper operations without introducing UIKit geometry types into the shared layout API.

Safe areas

Pages avoid all safe-area edges by default through ContentView.SafeAreaEdges. Choose specific edges when a page should extend under part of the system UI:

public PhotoPage()
{
    SafeAreaEdges = SafeAreaEdges.Leading |
                    SafeAreaEdges.Trailing |
                    SafeAreaEdges.Bottom;
    Content = new Image { Source = "hero" };
}

View.IgnoresSafeArea is a local escape hatch for an individual view. ScrollsUnderBars controls whether scrolling page content continues beneath navigation bars so UIKit can apply its normal translucent bar behavior.