# frameLayout(at:) and frameLayout(with:) in StackFrameLayout: A Complete Guide

> Explore StackFrameLayout's frameLayout(at:) and frameLayout(with:) methods. Quickly access child FrameLayouts by index or discover FrameLayouts managing specific UIViews through recursive search. Learn more now.

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

---

**`frameLayout(at:)`** returns the direct child `FrameLayout` at a specific index in constant time, while **`frameLayout(with:)`** performs a recursive search through the entire layout hierarchy to locate the `FrameLayout` managing a specific `UIView`.

FrameLayoutKit provides a DSL-based layout system for iOS that simplifies complex view hierarchies through `StackFrameLayout` containers. When building programmatic layouts, you often need to retrieve specific configuration objects after the initial setup, and these two methods in `StackFrameLayout` offer precise access to child layouts either by their positional index or by the target view they manage.

## Direct Index Access with frameLayout(at:)

The `frameLayout(at:)` method provides immediate access to a child layout based on its position in the internal storage array. This approach is optimal when you know the exact insertion order of your views.

### Implementation Details

In [`StackFrameLayout.swift`](https://github.com/kennic/framelayoutkit/blob/main/StackFrameLayout.swift), the implementation performs simple bounds checking before returning the element from the underlying `frameLayouts` array:

```swift
guard index >= 0 && index < frameLayouts.count else { return nil }
return frameLayouts[index]

```

This direct array lookup operates in **O(1)** constant time. The method returns an optional `FrameLayout?`, yielding `nil` if the supplied index falls outside the valid range. Because it accesses the internal representation directly, it respects the `ignoreHiddenView` flag inherited from the base `FrameLayout` class.

### Usage Example

```swift
import FrameLayoutKit

let stack = VStackLayout {
    $0.add(UILabel())  // Index 0
    $0.add(UILabel())  // Index 1  
    $0.add(UILabel())  // Index 2
}

// Retrieve the middle layout
if let secondLayout = stack.frameLayout(at: 1) {
    secondLayout.backgroundColor = .lightGray
}

```

## Hierarchical View Lookup with frameLayout(with:)

When you possess a reference to a `UIView` (perhaps from a gesture recognizer or delegate callback) and need to discover which `FrameLayout` controls it, use `frameLayout(with:)`. This method traverses the entire stack hierarchy, including nested `StackFrameLayout` instances.

### Recursive Traversal Logic

According to the source code in [`StackFrameLayout.swift`](https://github.com/kennic/framelayoutkit/blob/main/StackFrameLayout.swift) (lines 48-68), the method executes the following steps:

1. **Self-check**: If the stack's own `targetView` matches the search view, return `self`
2. **Linear search**: Iterate through `frameLayouts` using enumeration
3. **Match detection**: If a child's `targetView` equals the search view, return that child immediately
4. **Recursion**: If a child is itself a `StackFrameLayout`, recursively call `frameLayout(with:)` on that substack
5. **Early termination**: Set `stop = true` upon finding the first match to prevent unnecessary traversal

This algorithm runs in **O(n)** time complexity relative to the total number of frames in the hierarchy, plus the recursive depth for any nested stacks.

### Usage Example

```swift
// Locate layout by view reference
if let firstLabel = stack.frameLayout(at: 0)?.targetView {
    if let layout = stack.frameLayout(with: firstLabel) {
        layout.backgroundColor = .yellow
    }
}

```

## Performance Characteristics Comparison

Understanding the computational differences helps you select the appropriate method for your specific access pattern:

- **`frameLayout(at:)`** – **O(1)** constant time. Use this when you know the child index and need maximum performance.
- **`frameLayout(with:)`** – **O(n)** linear time. Use this when you only have a view reference and don't know its structural position.

Both methods are **read-only** operations that never modify the stack configuration or the underlying `frameLayouts` collection.

## Working with Nested StackLayouts

The recursive capability of `frameLayout(with:)` proves essential when dealing with complex, nested hierarchies. Consider a vertical stack containing a horizontal inner stack:

```swift
let innerStack = HStackLayout {
    $0.add(UIButton())  // Button at index 0
    $0.add(UIButton())  // Button at index 1
}

let outerStack = VStackLayout {
    $0.add(UILabel())
    $0.add(innerStack)  // Nested stack added as child
}

// Find a button deep inside the nested stack
if let button = innerStack.frameLayout(at: 0)?.targetView {
    let owner = outerStack.frameLayout(with: button)
    // Recursively traverses into innerStack automatically
    print("Found button managed by:", owner!)
}

```

In this scenario, calling `outerStack.frameLayout(with: button)` automatically descends into `innerStack` to locate the correct `FrameLayout` instance, whereas `outerStack.frameLayout(at: 0)` would only return the immediate child at that index (the `UILabel`).

## Summary

- **`frameLayout(at:)`** provides **O(1)** direct array access to child layouts by numeric index, returning `nil` for out-of-bounds requests
- **`frameLayout(with:)`** performs **O(n)** recursive searches through nested `StackFrameLayout` hierarchies to find layouts by their associated `targetView`
- Both methods respect the `ignoreHiddenView` flag and are implemented in [`StackFrameLayout.swift`](https://github.com/kennic/framelayoutkit/blob/main/StackFrameLayout.swift)
- These accessors are read-only and safe to call from any thread, though layout mutations should occur on the main thread

## Frequently Asked Questions

### What is the time complexity difference between frameLayout(at:) and frameLayout(with:)?

**`frameLayout(at:)`** operates in **O(1)** constant time because it performs a single array index lookup after bounds validation. **`frameLayout(with:)`** operates in **O(n)** linear time where *n* represents the total number of frames in the hierarchy, as it must potentially examine every layout node during its recursive descent.

### Can frameLayout(with:) find layouts inside nested StackFrameLayouts?

Yes. The method recursively traverses the entire layout hierarchy. When it encounters a child that is itself a `StackFrameLayout`, it automatically calls `frameLayout(with:)` on that substack until it finds a match or exhausts all possibilities.

### What happens if I pass an invalid index to frameLayout(at:)?

The method returns `nil`. The implementation explicitly guards against negative indices or values exceeding `frameLayouts.count - 1`, making it safe to call with unchecked indices without risking runtime exceptions.

### Do these methods respect the ignoreHiddenView setting?

Yes. Both methods operate on the internal `frameLayouts` collection, which already respects the `ignoreHiddenView` flag during layout calculations. However, note that these retrieval methods return the layout objects themselves regardless of visibility; the flag primarily affects layout computation rather than object access.