How to Use DoubleFrameLayout for Managing Two Views with Flexible Layout Options in FrameLayoutKit
DoubleFrameLayout is a concrete FrameLayout subclass that arranges exactly two child views (or nested layouts) either horizontally or vertically using distribution strategies like equal splits, custom ratios, or intrinsic sizing.
Managing two sibling views with precise layout requirements is straightforward using DoubleFrameLayout from the kennic/framelayoutkit repository. This specialized container provides granular control over axis alignment, space distribution, and overlap behavior through both programmatic APIs and a chainable DSL.
Core Architecture and Frame Structure
DoubleFrameLayout maintains two internal FrameLayout instances—frameLayout1 and frameLayout2—that serve as the actual containers for your target views. According to the source in [DoubleFrameLayout.swift](https://github.com/kennic/framelayoutkit/blob/master/FrameLayoutKit/Classes/DoubleFrameLayout.swift), these internal frames are added as subviews during initialization and automatically synchronized when configuration properties like ignoreHiddenView, debug, or allowContentSizing change.
The layout algorithm operates in three distinct phases:
- Measurement – The
sizeThatFits(_:ignoreHiddenView:)method calculates content sizes for each child based on the currentaxis,distribution,spacing, andedgeInsets. - Composition – The system determines how much space each pane receives according to the
NKLayoutDistributionstrategy. - Placement – The
layoutSubviews()method applies computed frames toframeLayout1andframeLayout2, accounting fortranslationOffsetor overlapping configurations.
Layout Distribution Strategies
The NKLayoutDistribution enum in DoubleFrameLayout.swift defines five distinct strategies for partitioning space between the two panes:
top/left– The first view (top in vertical, left in horizontal) occupies its intrinsic size, while the second view fills the remaining space.bottom/right– The reverse of above; the second view gets intrinsic sizing priority.equal– Both views split the available space 50/50, automatically adjusting if one pane is empty.split(ratio:)– Accepts a custom ratio array (e.g.,[0.3, 0.7]) for precise percentage-based allocation.center– Both views are centered within the container with optional spacing between them, collapsing empty panes to zero width.
Practical Implementation Examples
Basic Horizontal Layout with Intrinsic Sizing
This example places two labels side-by-side, giving the left label its intrinsic width while the right label occupies the remaining space:
let leftView = UILabel()
leftView.text = "Left"
let rightView = UILabel()
rightView.text = "Right"
let layout = DoubleFrameLayout { $0
.axis(.horizontal)
.distribution(.left)
.spacing(8)
.setLeft(leftView)
.setRight(rightView)
}
The .left distribution ensures frameLayout1 sizes to fit leftView exactly, while frameLayout2 stretches to fill the remaining width minus the 8-point spacing.
Equal-Split Vertical Layout with Overlap
For layered effects where both views share the same geometric bounds:
let top = UIView()
top.backgroundColor = .red
let bottom = UIView()
bottom.backgroundColor = .blue
let layout = DoubleFrameLayout(axis: .vertical, distribution: .equal, views: [top, bottom])
layout.isOverlapped = true
layout.spacing = 0
Setting isOverlapped = true causes both panes to occupy identical frames, useful for creating combined gesture targets or visual blending effects.
Custom Ratio Distribution with Chainable DSL
The companion file DoubleFrameLayout+Chainable.swift provides fluent operators <+ and +> for concise view assignment:
let left = UIView()
let right = UIView()
let layout = DoubleFrameLayout()
<+ left
+> right
.axis(.horizontal)
.distribution(.split(ratio: [0.3, 0.7]))
.spacing(12)
Here, <+ assigns left to frameLayout1 and +> assigns right to frameLayout2, distributing 30% of the width to the left pane and 70% to the right.
Centered Single-View Layout
When only one view is present, DoubleFrameLayout automatically collapses the empty pane:
let onlyView = UIButton()
onlyView.setTitle("Only", for: .normal)
let layout = DoubleFrameLayout { $0
.axis(.horizontal)
.distribution(.center)
.spacing(0)
.setLeft(onlyView)
}
The empty right pane collapses to zero width, centering the button within the container bounds.
Advanced Configuration Options
Beyond basic distribution, DoubleFrameLayout inherits robust capabilities from [FrameLayout.swift](https://github.com/kennic/framelayoutkit/blob/master/FrameLayoutKit/Classes/FrameLayout.swift):
translationOffset– Applies a positional offset to both child frames after layout calculation.shouldCacheSize– Enables size caching for performance optimization in scroll views.skeletonColor/isSkeletonMode– Activates placeholder loading states without additional view hierarchy changes.debug/debugColor– Visualizes layout boundaries for debugging complex interface structures.
Because the class reuses the base FrameLayout logic, it automatically handles intrinsic size propagation, hidden view management via ignoreHiddenView, and edge inset application across both panes.
Summary
DoubleFrameLayoutmanages exactly two views through internalframeLayout1andframeLayout2containers defined inDoubleFrameLayout.swift.- The
NKLayoutDistributionenum provides five strategies: intrinsic priority (left/top or right/bottom), equal splits, custom ratios, and centered alignment. isOverlappedenables layered layouts where both panes share identical bounds.- The chainable DSL in
DoubleFrameLayout+Chainable.swiftoffers<+and+>operators for declarative view assignment. - All layout calculations occur in
sizeThatFits(_:ignoreHiddenView:)andlayoutSubviews(), inheriting caching and debug features from the baseFrameLayoutclass.
Frequently Asked Questions
What is the difference between DoubleFrameLayout and StackFrameLayout?
DoubleFrameLayout is optimized specifically for exactly two child views with precise distribution control, while StackFrameLayout handles N views in a stack arrangement. According to the FrameLayoutKit source, DoubleFrameLayout uses dedicated frameLayout1 and frameLayout2 properties with ratio-based splitting, whereas stack layouts manage dynamic arrays of children.
How do I set custom width ratios between two views?
Use the .split(ratio:) distribution with an array of two CGFloat values representing percentages. For example, .distribution(.split(ratio: [0.25, 0.75])) allocates 25% of the available space to the first view and 75% to the second, as implemented in the sizeThatFits method of DoubleFrameLayout.swift.
Can DoubleFrameLayout handle overlapping views?
Yes. Setting the isOverlapped property to true forces both frameLayout1 and frameLayout2 to occupy the same calculated bounds during layoutSubviews(). This is useful for creating overlay effects or shared gesture targets while maintaining separate view hierarchies.
What happens if one of the two views is empty?
The layout algorithm automatically detects empty panes and collapses their ratio to zero. When using .equal or .split distributions, the non-empty view expands to fill the available space. With .center distribution, the single view centers within the container bounds.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →