allowContentVerticalGrowing and allowContentVerticalShrinking in FrameLayout: Controlling Vertical Resizing in iOS
FrameLayout's allowContentVerticalGrowing and allowContentVerticalShrinking Boolean flags control whether the target view can expand or compress its height relative to the container during layout calculations.
The kennic/framelayoutkit library provides flexible iOS layout management through FrameLayout, a class that wraps target views and calculates their frames dynamically. These two properties determine how the layout handles height adjustments when the container dimensions differ from the content's intrinsic size, allowing precise control over vertical space utilization.
Understanding the Vertical Resizing Flags
These Boolean properties on FrameLayout manage vertical dimension behavior during the layoutSubviews() cycle. Both default to false, which preserves the target view's natural content size unless explicitly configured otherwise.
allowContentVerticalGrowing
When set to true, this flag permits the target view's height to expand to the larger value between the container's height and the content's intrinsic height. According to the implementation in FrameLayoutKit/Classes/FrameLayout.swift (lines 886-894), this logic executes within the .top, .bottom, .center, and .fit vertical alignment branches:
if allowContentVerticalGrowing {
targetFrame.size.height = max(containerFrame.height, contentSize.height)
}
allowContentVerticalShrinking
When true (and only evaluated if allowContentVerticalGrowing is false), this flag allows the target view's height to reduce to the smaller value between the container height and content size:
else if allowContentVerticalShrinking {
targetFrame.size.height = min(containerFrame.height, contentSize.height)
}
Implementation Details in FrameLayout.swift
The vertical resizing logic resides in the layoutSubviews() method of FrameLayout.swift. The implementation evaluates both flags sequentially during frame calculation, ensuring that growing takes precedence when both flags are enabled. This design allows developers to specify exact resizing constraints without manual frame mathematics.
When both flags remain false (the default state), the target view maintains its intrinsic content height (contentSize.height) regardless of the container's actual height, effectively bypassing the automatic resizing logic.
Practical Usage Examples
Resizing a Wrapped Label
Configure a FrameLayout wrapping a UILabel to adapt vertically to its parent:
let label = UILabel()
label.text = "Dynamic text content that may require flexible height"
let layout = FrameLayout(targetView: label)
// Permit expansion when container has extra vertical space
layout.allowContentVerticalGrowing = true
// Permit compression when container is vertically constrained
layout.allowContentVerticalShrinking = true
layout.alignment.vertical = .center
layout.layoutSubviews()
Propagation in Composite Layouts
StackFrameLayout automatically forwards these flags to all child layouts. As implemented in FrameLayoutKit/Classes/StackFrameLayout.swift (lines 78-84), setting the properties on a stack applies the behavior collectively to its frameLayouts array:
let stack = StackFrameLayout()
stack.allowContentVerticalGrowing = true // All children can expand
stack.allowContentVerticalShrinking = false // Children maintain minimum height
DoubleFrameLayout similarly mirrors these flags across its two child layouts, ensuring that paired views maintain consistent vertical resizing behavior throughout the composite layout structure.
Summary
allowContentVerticalGrowingexpands the target view height tomax(containerHeight, contentHeight)when enabled inFrameLayout.swiftallowContentVerticalShrinkingreduces the target view height tomin(containerHeight, contentHeight)when enabled and growing is disabled- Both properties default to
false, preserving the intrinsic content dimensions defined bycontentSize.height StackFrameLayoutpropagates these flags to child layouts through property forwarding for coordinated resizing- The core logic executes within vertical alignment branches (
.top,.bottom,.center,.fit) at lines 886-894 ofFrameLayoutKit/Classes/FrameLayout.swift
Frequently Asked Questions
What happens if both allowContentVerticalGrowing and allowContentVerticalShrinking are set to true?
When both flags are enabled, the growing logic takes precedence. In FrameLayout.swift, the implementation checks allowContentVerticalGrowing first via an if statement, while the shrinking logic resides in a subsequent else if block. Therefore, the target view height will always expand to the larger of the container or content dimensions, effectively ignoring the shrinking condition during that layout pass.
Do these properties affect horizontal dimensions?
No. These flags specifically control vertical axis behavior only. The FrameLayout class provides separate mechanisms for horizontal resizing. The source code explicitly modifies targetFrame.size.height within the vertical alignment calculation branches, leaving width calculations and contentSize.width unaffected by these particular flags.
How do StackFrameLayout and DoubleFrameLayout handle these properties?
StackFrameLayout propagates both flags to all child frame layouts through property forwarding, as implemented in StackFrameLayout.swift. Similarly, DoubleFrameLayout mirrors these flags across its composite child layouts, ensuring consistent vertical resizing behavior throughout complex layout hierarchies without requiring manual configuration of each sub-layout individually.
What is the default behavior when these flags are false?
When both allowContentVerticalGrowing and allowContentVerticalShrinking remain false (the default), the target view maintains its intrinsic content height (contentSize.height) regardless of the container's actual height. The layout respects the content's natural dimensions without automatic expansion or compression during the layoutSubviews() calculation.
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 →