# GridFrameLayout Dynamic Column Sizing: How isAutoSize Manages Adaptive Layouts in FrameLayoutKit

> Discover how GridFrameLayout with isAutoSize dynamically manages column sizing. Learn how arrangeViews calculates layout dimensions to perfectly fit your adaptive FrameLayoutKit content.

- Repository: [Nam Kennic/framelayoutkit](https://github.com/kennic/framelayoutkit)
- Tags: deep-dive
- Published: 2026-03-05

---

**When `isAutoSize` is enabled in `GridFrameLayout`, the `arrangeViews(autoColumns:)` method dynamically calculates either row or column counts based on the layout axis, using `ceil(viewCount / fixedDimension)` to ensure all child views fit within the specified constraints.**

`GridFrameLayout` in the [kennic/framelayoutkit](https://github.com/kennic/framelayoutkit) repository provides a flexible grid system for iOS development. When the `isAutoSize` property is enabled, the layout engine automatically adjusts column or row counts to accommodate varying numbers of child views without manual recalculation.

## Core Auto-Size Logic in arrangeViews(autoColumns:)

The dynamic sizing implementation resides in [`GridFrameLayout.swift`](https://github.com/kennic/framelayoutkit/blob/main/GridFrameLayout.swift) within the `arrangeViews(autoColumns:)` method. This routine serves as the central layout coordinator, invoked whenever the view hierarchy changes, when the view's size changes, or when `isAutoSize` is toggled.

When `isAutoSize` evaluates to `true`, the method branches based on the current **axis** property:

```swift
func arrangeViews(autoColumns: Bool = true) {
    guard viewCount > 0 else { return }

    var numberOfRows = stackLayout.frameLayouts.count
    if isAutoSize {
        // Horizontal axis – compute rows from the fixed column count
        if axis == .horizontal, columns > 0 {
            let fitRows = max(Int(ceil(Double(viewCount) / Double(columns))), 1)
            if fitRows != rows {
                rows = fitRows                // updates rows → triggers layout
                numberOfRows = fitRows
            }
        }
        // Vertical axis – compute columns from the fixed row count
        else if axis == .vertical, rows > 0 {
            let fitColumn = max(Int(ceil(Double(viewCount) / Double(rows))), 1)
            if fitColumn != columns {
                columns = fitColumn           // updates columns → triggers layout
            }
        }
    }
    // ...
}

```

*Source: [[`GridFrameLayout.swift`](https://github.com/kennic/framelayoutkit/blob/main/GridFrameLayout.swift), lines 33-48](https://github.com/kennic/framelayoutkit/blob/master/FrameLayoutKit/Classes/GridFrameLayout.swift#L33-L48)*

## Axis-Dependent Dynamic Sizing

The `GridFrameLayout` adapts its calculation strategy based on whether the layout flows horizontally or vertically.

### Horizontal Axis: Dynamic Row Calculation with Fixed Columns

When `axis` is set to `.horizontal` and `isAutoSize` is enabled, the `columns` property remains fixed (either as specified by the developer or defaulting to 0). The layout engine calculates the required number of rows using ceiling division:

```swift
let fitRows = max(Int(ceil(Double(viewCount) / Double(columns))), 1)

```

This ensures that all child views fit within the specified column count, adding rows as necessary when the view count increases.

### Vertical Axis: Dynamic Column Sizing with Fixed Rows

Conversely, when `axis` is `.vertical`, the `rows` property remains fixed while the system dynamically calculates the column count:

```swift
let fitColumn = max(Int(ceil(Double(viewCount) / Double(rows))), 1)

```

This mode is particularly useful for creating horizontally scrolling grids or adaptive flow layouts where you want to maintain a specific row height while allowing columns to expand based on content.

## Width-Based Column Optimization Using maxColumnWidth

Beyond the basic `isAutoSize` functionality, `GridFrameLayout` supports dynamic column sizing based on available width through the `maxColumnWidth` property. When this property is non-zero and `autoColumns` remains `true`, the layout recalculates how many columns fit into the current bounds:

```swift
if axis == .horizontal {
    if autoColumns, maxColumnWidth > 0 {
        var viewSize = stackLayout.bounds.size
        if viewSize == .zero { viewSize = bounds.size }
        // Compute how many columns fit into the current width
        let fitColumns = max(Int(viewSize.width / maxColumnWidth), max(initColumns, 1))
        if columns != fitColumns {
            columns = fitColumns               // triggers a second arrange pass
            arrangeViews(autoColumns: false)   // re-layout with the new column count
            return
        }
    }
    // ...
}

```

*Source: [[`GridFrameLayout.swift`](https://github.com/kennic/framelayoutkit/blob/main/GridFrameLayout.swift), lines 52-60](https://github.com/kennic/framelayoutkit/blob/master/FrameLayoutKit/Classes/GridFrameLayout.swift#L52-L60)*

This mechanism works in conjunction with `isAutoSize` to provide responsive grid layouts that adapt to both content count and container width.

## Layout Trigger Points and Update Mechanisms

The dynamic sizing system responds to several trigger points defined in [`GridFrameLayout.swift`](https://github.com/kennic/framelayoutkit/blob/main/GridFrameLayout.swift):

### Size Change Detection

The `layoutSubviews()` override monitors bounds changes when `maxColumnWidth` is active:

```swift
if maxColumnWidth > 0, lastSize != bounds.size {
    lastSize = bounds.size
    arrangeViews()
}

```

*Source: [[`GridFrameLayout.swift`](https://github.com/kennic/framelayoutkit/blob/main/GridFrameLayout.swift), lines 7-10](https://github.com/kennic/framelayoutkit/blob/master/FrameLayoutKit/Classes/GridFrameLayout.swift#L7-L10)*

### Property Observers

Changes to `isAutoSize`, `axis`, `rows`, `columns`, `maxColumnWidth`, or the underlying `views` array automatically invoke `arrangeViews()` through their `didSet` observers, ensuring the layout remains synchronized with state changes without manual intervention.

## Summary

- **`arrangeViews(autoColumns:)`** serves as the central layout coordinator in [`GridFrameLayout.swift`](https://github.com/kennic/framelayoutkit/blob/main/GridFrameLayout.swift), implementing all dynamic sizing logic.
- When **`isAutoSize`** is enabled, the layout calculates missing dimensions using `ceil(viewCount / fixedDimension)` to ensure complete view coverage.
- **Horizontal axis** layouts fix the column count and compute rows dynamically, while **vertical axis** layouts fix the row count and compute columns dynamically.
- The **`maxColumnWidth`** property enables width-responsive column calculation, triggering secondary layout passes when container bounds change.
- Layout updates occur automatically through `layoutSubviews()` overrides and `didSet` property observers on key configuration properties.

## Frequently Asked Questions

### What happens when isAutoSize is disabled in GridFrameLayout?

When `isAutoSize` is set to `false`, `GridFrameLayout` respects the explicit `rows` and `columns` values set by the developer without automatic calculation. The `arrangeViews` method skips the dynamic sizing logic, using only the predefined grid dimensions to position child views, which may result in empty cells or clipped content if the view count exceeds the fixed grid capacity.

### How does GridFrameLayout handle device rotation with dynamic column sizing?

During device rotation or any bounds change, `GridFrameLayout` detects size changes in `layoutSubviews()` when `maxColumnWidth` is active. The method compares `lastSize` against `bounds.size` and invokes `arrangeViews()` to recalculate the column count based on the new width. This ensures the grid adapts responsively to orientation changes while maintaining the maximum column width constraint.

### Can I use both maxColumnWidth and isAutoSize simultaneously?

Yes, these properties work complementarily. When both are enabled, `isAutoSize` first calculates the required rows or columns based on view count and axis direction. Subsequently, if `maxColumnWidth` is set and `autoColumns` remains true, the layout performs a secondary calculation to determine how many columns fit within the available width. This two-phase approach allows the grid to adapt to both content quantity and container dimensions.

### What is the difference between horizontal and vertical axis behavior in auto-size mode?

In horizontal axis mode with `isAutoSize` enabled, the `columns` property remains fixed (as specified by the developer) and the system dynamically calculates the required `rows` using `ceil(viewCount / columns)`. Conversely, in vertical axis mode, the `rows` property remains fixed while the system dynamically calculates the `columns` needed to display all views using `ceil(viewCount / rows)`. This axis-dependent behavior determines whether the grid expands vertically or horizontally to accommodate content.