Stack Views

Layout

TTBaseUIKit provides three stack view variants built on UIStackView and UIScrollView: a base configurable stack, a vertical scrollable stack, and a horizontal scrollable stack. All support the kit's default spacing and keyboard dismiss behaviors.


📦 Classes

ClassBaseDirectionUse Case
TTBaseUIStackViewUIStackViewConfigurableInline arranged subviews, fixed layouts
TTBaseScrollUIStackViewUIScrollViewVerticalDynamic content that may exceed screen height
TTBaseScrollHorizontalUIStackViewUIScrollViewHorizontalTag chips, horizontal carousels, filter pills

🚀 Usage

TTBaseUIStackView — Basic Arranged Views

// Vertical stack with default spacing
let vStack = TTBaseUIStackView(
    axis: .vertical,
    spacing: 16,
    alignment: .fill
)
vStack.addArrangedSubview(titleLabel)
vStack.addArrangedSubview(subtitleLabel)
vStack.addArrangedSubview(actionButton)

// Horizontal stack (e.g., icon + label row)
let hStack = TTBaseUIStackView(
    axis: .horizontal,
    spacing: 8,
    alignment: .center,
    distributionValue: .fill
)
hStack.addArrangedSubview(iconView)
hStack.addArrangedSubview(nameLabel)

Background Color on Stack View

// UIStackView has no backgroundColor — use this helper instead
let cardStack = TTBaseUIStackView(
    axis: .vertical,
    spacing: 12,
    alignment: .fill
)
// Inserts a UIView subview with corner radius as background
cardStack.setBackgroundColorByView(
    color: UIColor.systemGray6,
    conerRadius: 12
)

TTBaseScrollUIStackView — Vertical Scrollable Form

// Create the inner stack
let innerStack = TTBaseUIStackView(
    axis: .vertical,
    spacing: TTSize.P_CONS_DEF,
    alignment: .fill
)
innerStack.addArrangedSubview(nameField)
innerStack.addArrangedSubview(emailField)
innerStack.addArrangedSubview(passwordField)
innerStack.addArrangedSubview(loginButton)

// Wrap in scrollable container with padding
let scrollStack = TTBaseScrollUIStackView(
    with: innerStack,
    padding: (16, 16, 16, 32)   // (leading, top, trailing, bottom)
)
view.addSubview(scrollStack)
scrollStack.setFullContraints(constant: 0)

TTBaseScrollHorizontalUIStackView — Horizontal Chips

let chipStack = TTBaseUIStackView(
    axis: .horizontal,
    spacing: 8,
    alignment: .center,
    distributionValue: .fill
)
categories.forEach { category in
    let chip = CategoryChipView(title: category)
    chipStack.addArrangedSubview(chip)
}

let scrollChips = TTBaseScrollHorizontalUIStackView(
    with: chipStack,
    padding: (16, 0, 16, 0)
)
scrollChips.setHeightAnchor(constant: 44)

Subclass to set defaults

// Override computed properties instead of passing arguments
class FormScrollView: TTBaseScrollUIStackView {
    override var bgPanelColor: UIColor { .systemBackground }
    override var isSetWidthContraint: Bool { true }
}

📖 API Reference

TTBaseUIStackView

Property / MethodTypeDescription
axisContraintNSLayoutConstraint.AxisStack axis (default: .vertical)
spacingContraintCGFloatSpacing between views (default: P_CONS_DEF)
alignmentContraintUIStackView.AlignmentAlignment (default: .center)
distributionValueUIStackView.DistributionDistribution (default: .equalSpacing)
setBackgroundColorByView(color:conerRadius:)VoidAdd background UIView behind arranged subviews

TTBaseScrollUIStackView / Horizontal

PropertyTypeDescription
baseStackViewTTBaseUIStackViewInner stack view reference
pading(CGFloat,CGFloat,CGFloat,CGFloat)Leading, Top, Trailing, Bottom padding
bgPanelColorUIColorBackground color (default: clear; override in subclass)
isSetWidthContraintBoolPin inner stack width to scroll width (true = no horizontal scroll)
Pro Tip: UIStackView ignores backgroundColor — always use setBackgroundColorByView(color:conerRadius:) for panel-style backgrounds. It inserts a plain UIView at z-position 0 automatically.