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.
Margin belongs to every View and reserves space outside it. Padding belongs to containers and reserves space between the container's bounds and its content.
System content insets
Set a container's SystemInsetEdges to add the containing page controller's current UIKit system margins on selected edges. These insets are added to Padding; they do not change the container's own bounds or its Margin.
For scrolling pages, apply them to the panel inside the scroll view. The viewport and scroll indicators then remain edge-to-edge while the content follows UIKit's standard margins:
CollectionView applies the same property to its compositional layout rather than its scroll-view insets, so cells, headers, and footers follow the margins without moving the scroll indicators:
Use LayoutEdges.Leading, Trailing, Top, or Bottom individually, combine them with |, or use the Horizontal, Vertical, and All groups. UIKit resolves the values from the live page, and SkeleKit updates layout if they change.
Alignment
Horizontal and vertical alignment decide where a view sits when its parent offers more room than it needs.
Start,Center, andEndkeep the measured size and position it along that axis.Stretchuses 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:
Sizestores width and height.Pointstores an x and y coordinate.Rectcombines an origin and size.Thicknessstores 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 keep their content inside all safe-area edges by default through ContentView.SafeAreaEdges. The ContentView itself always fills the controller, so its Background continues beneath system UI. Choose specific edges when the content should extend under part of that UI:
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.
A content-detent sheet has no bottom safe area on iPad, so its content would sit against the sheet's edge. ContentView.MinimumContentInsets raises the content insets on any side where the safe area and padding together fall short; the larger system inset is used, so a home indicator is never padded twice: