# FrameLayoutKit heightRatio Property: Controlling Aspect Ratio and Intrinsic Size Behavior in Swift

> Discover how FrameLayoutKit's heightRatio property controls aspect ratio and intrinsic size behavior in Swift. Automatically manage view dimensions with this powerful tool.

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

---

**The `heightRatio` property in FrameLayoutKit forces a view’s height to be a calculated multiple of its width, automatically disabling intrinsic height sizing whenever the ratio is greater than zero.**

The `heightRatio` property is a core feature of `FrameLayout` (and its subclasses) in the [kennic/framelayoutkit](https://github.com/kennic/framelayoutkit) repository. It provides a declarative way to enforce fixed aspect ratios—such as 1:1 squares or 16:9 thumbnails—by overriding the target view’s intrinsic content size. When activated, the layout engine computes height dynamically from the final width, ensuring consistent proportions regardless of content changes.

## What Is the heightRatio Property?

`heightRatio` is a `CGFloat` property defined on the `FrameLayout` class that expresses height as a multiplier of width.

- **Default value**: `0` (disabled)
- **Active state**: Any positive value (e.g., `1.0`, `0.75`, `1.333`)
- **Effect**: When greater than zero, the layout ignores the target view’s intrinsic height and calculates `height = width × heightRatio`

This mechanism is particularly useful for image views, video players, or card components where the aspect ratio must remain constant even when the container resizes.

## How heightRatio Interacts with Intrinsic Size

The interaction between `heightRatio` and intrinsic sizing is governed by an automatic toggle in the property observer and conditional logic inside the layout engine.

### Automatic Disabling of Intrinsic Size Mode

When you set a positive `heightRatio`, the property’s `didSet` observer automatically disables intrinsic-size mode to prevent conflicts. This is implemented in [`FrameLayoutKit/Classes/FrameLayout.swift`](https://github.com/kennic/framelayoutkit/blob/main/FrameLayoutKit/Classes/FrameLayout.swift) (lines 46–52):

```swift
public var heightRatio: CGFloat = 0 {
    didSet {
        if heightRatio > 0 {
            isIntrinsicSizeEnabled = false   // Disables intrinsic height
        }
    }
}

```

By setting `isIntrinsicSizeEnabled` to `false`, the layout engine knows to ignore the target view’s `intrinsicContentSize` height and instead use the ratio-based calculation.

### Size Calculation Logic in sizeThatFits

During layout, `FrameLayout` overrides `sizeThatFits(_:)` to apply the ratio constraint. The logic prioritizes `heightRatio` over intrinsic sizing, as shown in [`FrameLayout.swift`](https://github.com/kennic/framelayoutkit/blob/main/FrameLayout.swift) (lines 82–88):

```swift
if heightRatio > 0 {
    // Width is determined by intrinsic size (if enabled) or available space
    result.width = isIntrinsicSizeEnabled ? contentSizeThatFits(size: contentSize).width
                                          : contentSize.width
    // Height is strictly derived from width using the ratio
    result.height = result.width * heightRatio
} else {
    // Standard intrinsic-size calculation when ratio is disabled
    result = contentSizeThatFits(size: contentSize)
    if !isIntrinsicSizeEnabled {
        result.width = contentSize.width
    }
}

```

When `heightRatio` is positive, the height becomes a deterministic function of the width, effectively locking the aspect ratio. When `heightRatio` is `0` (default), the system falls back to standard intrinsic content size behavior.

## Practical Examples: Using heightRatio in FrameLayoutKit

### Creating a Square Layout (1:1 Aspect Ratio)

To force a view to remain square regardless of its content:

```swift
let layout = FrameLayout()
layout.targetView = UIImageView(image: myImage)
layout.heightRatio = 1.0  // height equals width
// isIntrinsicSizeEnabled is automatically set to false

```

### Setting a Custom Aspect Ratio (4:3 or 75%)

For a landscape thumbnail where height should be 75% of the width:

```swift
let layout = FrameLayout()
layout.targetView = myContentView
layout.heightRatio = 0.75  // 3:4 ratio (height = 0.75 × width)
layout.allowContentHorizontalGrowing = true

```

### Chainable DSL API Usage

FrameLayoutKit provides a fluent interface via `FrameLayout+Chainable.swift`:

```swift
let layout = FrameLayout()
    .heightRatio(1.333)  // 4:3 aspect ratio
    .allowContentHorizontalGrowing(true)
    .target(imageView)

```

## Key Source Files and Implementation Details

The `heightRatio` functionality is implemented across the following files in the [kennic/framelayoutkit](https://github.com/kennic/framelayoutkit) repository:

- **[`FrameLayoutKit/Classes/FrameLayout.swift`](https://github.com/kennic/framelayoutkit/blob/main/FrameLayoutKit/Classes/FrameLayout.swift)** – Contains the `heightRatio` property definition (line 46), its `didSet` observer that disables intrinsic sizing, and the `sizeThatFits(_:)` override (lines 82–88) that applies the ratio calculation.
- **`FrameLayoutKit/Classes/Extensions/FrameLayout+Chainable.swift`** – Provides the `heightRatio(_:)` method for DSL-style configuration.
- **[`FrameLayoutKit/Classes/ScrollStackView.swift`](https://github.com/kennic/framelayoutkit/blob/main/FrameLayoutKit/Classes/ScrollStackView.swift)** – Exposes `heightRatio` on stack views, demonstrating how the property propagates to child layouts.
- **[`FrameLayoutKit/Classes/StackFrameLayout.swift`](https://github.com/kennic/framelayoutkit/blob/main/FrameLayoutKit/Classes/StackFrameLayout.swift)** – Utilizes `heightRatio` when calculating flexible child layouts within stacks.

## Summary

- **`heightRatio`** is a `CGFloat` property on `FrameLayout` that enforces a fixed aspect ratio by calculating height as a multiple of width.
- When set to any value greater than `0`, the property automatically disables `isIntrinsicSizeEnabled`, preventing the target view’s intrinsic height from affecting layout.
- The calculation occurs in `sizeThatFits(_:)`, where positive ratios override intrinsic sizing and force `height = width × heightRatio`.
- Setting `heightRatio` to `0` (the default) restores standard intrinsic content size behavior.
- The property is available through both direct assignment and a chainable DSL API.

## Frequently Asked Questions

### What happens to intrinsic height when heightRatio is set?

When you assign a positive value to `heightRatio`, the property’s `didSet` observer automatically sets `isIntrinsicSizeEnabled` to `false`. This disables the layout engine’s reliance on the target view’s `intrinsicContentSize` height, ensuring that height is calculated solely from the width multiplied by the ratio.

### Can I use heightRatio with StackFrameLayout?

Yes. `StackFrameLayout` inherits from `FrameLayout` and supports `heightRatio` for its child layouts. When a child within a stack has a positive `heightRatio`, the stack layout engine respects the calculated height during its measurement pass, making it useful for creating grids or lists with fixed aspect ratio items.

### How do I disable heightRatio and return to intrinsic sizing?

Set `heightRatio` back to `0` (the default value). When the ratio is `0`, the `sizeThatFits(_:)` implementation in [`FrameLayout.swift`](https://github.com/kennic/framelayoutkit/blob/main/FrameLayout.swift) skips the ratio-based calculation and falls back to the standard intrinsic content size logic, using `contentSizeThatFits(size:)` to determine dimensions.

### Does heightRatio work with UILabel intrinsic content size?

Yes, but with an important caveat. When you apply a positive `heightRatio` to a `FrameLayout` wrapping a `UILabel`, the layout disables intrinsic sizing and calculates height from the width. This means the label’s text will no longer automatically expand the height to fit its content; instead, the height is constrained by the ratio, potentially truncating text unless you handle it with `numberOfLines` or auto-shrink settings.