### Start Local Development Server Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/README.mdx Starts a local development server for live preview and hot-reloading. Changes are reflected without server restart. ```bash yarn start ``` -------------------------------- ### Basic ZStack Usage Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/zstack.mdx A basic example of using ZStack to layer background and a label. ```swift var body: Layout { ZStack { background label } } ``` -------------------------------- ### Install Dependencies Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/README.mdx Installs project dependencies using Yarn. ```bash yarn ``` -------------------------------- ### Apply Custom Alignment Guide in HStack Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/alignment-guides.mdx This example demonstrates applying the custom '.emojiTitle' vertical alignment guide to an HStack. It also shows how to use the alignmentGuide modifier on individual views within the stack to control their positioning relative to the custom guide. ```swift var body: Layout { VStack(spacing: 30) { titleView HStack(alignment: .emojiTitle, spacing: 16) { for emojiViewData in emojiViews { VStack { emojiViewData.emojiView emojiViewData.emojiTitleView .alignmentGuide(.emojiTitle) { _ in 0 } emojiViewData.emojiDescriptionView } } } } } ``` -------------------------------- ### Basic HFlow Usage Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/hflow.mdx A simple example demonstrating how to use HFlow with its default parameters to arrange icon, label, and Button elements. ```swift var body: Layout { HFlow { icon label Button } } ``` -------------------------------- ### Basic VFlow Usage Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/vflow.mdx A simple example demonstrating how to use VFlow to arrange a few child elements. ```swift var body: Layout { VFlow { icon label Button } } ``` -------------------------------- ### Applying Flexible Frame in HStack Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/flexible-frame.mdx Example demonstrating how to apply `minWidth` and `maxWidth` constraints to a label within an `HStack`. ```swift var body: Layout { HStack { label1 .frame(minWidth: 40, maxWidth: 80) label2 } } ``` -------------------------------- ### Basic HStack Usage Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/hstack.mdx A basic example of using HStack to arrange an icon, a label, and a spacer horizontally. ```swift var body: Layout { HStack { icon label Spacer() } } ``` -------------------------------- ### Basic @QuickLayout View Example Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/how-to-use/quick-layout-macro.mdx Demonstrates a simple UIView subclass using the @QuickLayout macro to define its layout using a declarative 'body' property. This view contains a label and an image arranged horizontally. ```swift import QuickLayout @QuickLayout final class MyView: UIView { private let label = { let label = UILabel() label.text = "Hello World!" return label }() private let image = { let image = UIImageView() image.image = UIImage(systemName: "globe.americas") return image }() var body: Layout { HStack { label Spacer(8) image } } } ``` -------------------------------- ### Element Alignment Guide Extension Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/alignment-guides.mdx This snippet shows the available extensions for the Element type to define alignment guides for both horizontal and vertical alignments. These methods allow you to specify custom alignment logic using a closure. ```swift extension Element { func alignmentGuide(_ horizontalAlignment: HorizontalAlignment, computeValue: @escaping @Sendable (ViewDimensions) -> CGFloat) -> Element func alignmentGuide(_ verticalAlignment: VerticalAlignment, computeValue: @escaping @Sendable (ViewDimensions) -> CGFloat) -> Element } ``` -------------------------------- ### Example: Applying Layout Priority in HStack Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/layout-priority.mdx Demonstrates using layoutPriority to give the profilePhoto a higher priority (1) for space allocation within an HStack, ensuring it measures first with a larger portion of available space. ```swift var body: Layout { HStack { profilePhoto .aspectRatio(CGSize(width: 1, height: 1)) .layoutPriority(1) Spacer(8) titleLabel Spacer(8) bodyLabel Spacer() button } } ``` -------------------------------- ### Define Custom Alignment Guides Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/alignment-guides.mdx This snippet shows how to define a custom vertical alignment guide named '.emojiTitle' by creating a custom AlignmentID. This custom guide can then be used to align views within stacks. ```swift extension VerticalAlignment { private struct EmojiTitleAlignment: AlignmentID { static func defaultValue(in context: ViewDimensions) -> CGFloat { context[VerticalAlignment.bottom] } } static let emojiTitle = VerticalAlignment( EmojiTitleAlignment.self ) } ``` -------------------------------- ### Manual Imperative Layout Example Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/concepts/double-measurements.mdx Demonstrates a manual, imperative layout approach in UIKit where each view is measured exactly once. This method requires more boilerplate code but is efficient as the developer controls the measurement order. ```swift // Measure the image view once let imageViewSize = imageView.sizeThatFits(availableSize) imageView.frame = CGRect(x: X, y: Y, width: imageViewSize.width, height: imageViewSize.height) // Measure the label once, taking into account image width + padding let labelAvailableWidth = availableSize.width - imageViewSize.width - padding let labelSize = label.sizeThatFits(CGSize(width: labelAvailableWidth, height: availableSize.height)) label.frame = CGRect(x: X, y: Y, width: labelSize.width, height: labelSize.height) ``` -------------------------------- ### Applying Background Modifier Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/background.mdx Example of how to apply the background modifier to an element in QuickLayout. This positions the backgroundView within the frame of the profilePhoto element. ```swift var body: Layout { profilePhoto .background { backgroundView } } ``` -------------------------------- ### SwiftUI Double Measurement Example Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/concepts/double-measurements.mdx Illustrates a SwiftUI layout that, under the hood, measures each subview multiple times with varying proposed sizes. This can lead to performance costs, especially with multiple text elements. ```swift HStack { Text("Lorem ipsum ...") Image("someImage") } ``` -------------------------------- ### SwiftUI Triple Measurement Example Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/concepts/double-measurements.mdx Shows a more complex SwiftUI layout where each Text view is measured twice before a final measurement. This multiplication of measurement costs can cause performance issues in scrolling lists. ```swift HStack { VStack { Text("Lorem ipsum ...") Text("Lorem ipsum ...") Text("Lorem ipsum ...") } VStack { Image("someImage") Image("someImage") Image("someImage") } } ``` -------------------------------- ### Using Overlay to Add a Button on a Photo Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/overlay.mdx Example of using the overlay modifier to position a resizable button on top of a profile photo. The button will be centered by default. ```swift var body: Layout { VStack { profilePhoto .overlay { button.resizable() } Spacer(8) label } } ``` -------------------------------- ### Constrained Size in HStack Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/constrained-size.mdx Example of using constrainedSize to limit the maximum dimensions of a profile image within an HStack, ensuring it fits within 80x80 points. ```swift var body: Layout { HStack { profileImageView .resizable() .constrainedSize(maxWidth: 80, maxHeight: 80) label } } ``` -------------------------------- ### Implement a Custom Vertical Alignment Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/custom-alignments.mdx Define a custom vertical alignment by creating an `AlignmentID` and extending `VerticalAlignment`. This example aligns views at one-third of their height. ```swift struct FirstThirdAlignment: AlignmentID { static func defaultValue(in context: ViewDimensions) -> CGFloat { context.height / 3 } } extension VerticalAlignment { static let firstThirdAlignment = VerticalAlignment(FirstThirdAlignment.self) } ``` -------------------------------- ### Define a Custom Alignment ID Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/custom-alignments.mdx Create a struct conforming to `AlignmentID` to define a custom alignment guide. This is the first step in creating custom alignments. ```swift struct MyCustomAlignment: AlignmentID { static func defaultValue(in context: ViewDimensions) -> CGFloat } ``` -------------------------------- ### Flexible Spacer with two views in HStack Source: https://github.com/facebook/quicklayout/blob/main/README.md When used with multiple views in an HStack, a flexible Spacer will distribute space between them. This example shows a spacer between two views. ```swift var body: Layout { HStack { view1 Spacer() view2 } } ``` -------------------------------- ### Applying Aspect Ratio to an ImageView Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/aspect-ratio.mdx Example of using the aspectRatio modifier on an imageView within a VStack. The imageView is set to be resizable and constrained to a 3:2 aspect ratio. ```swift var body: Layout { VStack { imageView .resizable() .aspectRatio(CGSize(width: 3, height: 2)) Spacer(8) label } } ``` -------------------------------- ### Using Layout Priority to Avoid Double Measurements Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/concepts/double-measurements.mdx Assign a higher layout priority to a view to influence QuickLayout's measurement order and prevent double measurements of sibling views. This example prioritizes a VStack containing buttons. ```swift HStack { VStack { label1 label2 label2 } VStack { aSmallCustomButton1 aSmallCustomButton2 aSmallCustomButton3 } /// Raising the layout priority to avoid double measuring /// the first VStack with labels. .layoutPriority(1) } ``` -------------------------------- ### Use Custom Alignment in a Layout Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/custom-alignments.mdx Apply a custom vertical alignment to an `HStack` to arrange child views. This example uses the `firstThirdAlignment` to align three `VStack`s. ```swift @QuickLayout final class CustomAlignmentView: UIView { private let colorViews = (0...8).map { index in let view = UIView() view.backgroundColor = .systemBlue return view } private let labels = (0...8).map { index in let label = UILabel() label.text = "\(index)" label.textColor = .white label.font = .monospacedDigitSystemFont(ofSize: 18, weight: .medium) return label } var body: Layout { HStack(alignment: .firstThirdAlignment, spacing: 2) { VStack(spacing: 2) { colorViews[0].overlay { labels[0] } colorViews[1].overlay { labels[1] } colorViews[2].overlay { labels[2] } }.frame(height: 140) VStack(spacing: 2) { colorViews[3].overlay { labels[3] } colorViews[4].overlay { labels[4] } colorViews[5].overlay { labels[5] } }.frame(height: 250) VStack(spacing: 2) { colorViews[6].overlay { labels[6] } colorViews[7].overlay { labels[7] } colorViews[8].overlay { labels[8] } }.frame(height: 180) } .padding(20) } } ``` -------------------------------- ### VFlow with Custom Spacing Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/vflow.mdx Applies custom spacing between items and lines in a VFlow layout. Note: The example incorrectly uses HFlow in the source, but the intent is to show spacing for VFlow. ```swift var body: Layout { HFlow(itemSpacing: 8, lineSpacing: 10) { icon label Button } } ``` -------------------------------- ### VFlow with Center Line Alignment Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/vflow.mdx Demonstrates setting the vertical alignment for lines within VFlow to the center. Note: The example incorrectly uses HFlow in the source, but the intent is to show line alignment for VFlow. ```swift var body: Layout { HFlow(lineAlignment: .center) { icon label Button } } ``` -------------------------------- ### Showcase App Command Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/intro.mdx Run the showcase app to see QuickLayout in action. This command is specific to the fbsource environment. ```bash arc showcase QuickLayout ``` -------------------------------- ### Basic VStack Usage Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/vstack.mdx Demonstrates the basic usage of VStack to arrange multiple views vertically. ```swift var body: Layout { VStack { view1 view2 view3 } } ``` -------------------------------- ### Build Static Website Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/README.mdx Generates static website content for deployment. The output is placed in the 'build' directory. ```bash yarn build ``` -------------------------------- ### Override bodyContainerView Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/how-to-use/quick-layout-macro-bodyContainerView.mdx Override the `bodyContainerView` property to specify an alternative container view for subviews. This example shows how to use a custom `contentView` as the container. ```swift import QuickLayout @QuickLayout final class ExperimentedView: UIView { let contentView = UIView() init() { super.init(frame: .zero) addsSubview(contentView) } override public var bodyContainerView: UIView { contentView /// This will be the container view for the body. } var body: Layout { ... } } ``` -------------------------------- ### Applying Padding to Elements Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/padding.mdx Demonstrates various ways to apply padding to elements within a VStack. ```swift var body: Layout { VStack { label1 .padding(8) label2 .padding(.leading, 8) label3 .padding(.horizontal, 8) label4 .padding([.leading, .bottom], 8) label5 .padding([.horizontal, .bottom], 8) label6 .padding(.horizontal, 8) .padding(.vertical, 16) label5 .padding(EdgeInsets(top: 10, leading: 20, bottom: 30, trailing: 40)) } } ``` -------------------------------- ### Manual UIView Integration with QuickLayout Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/how-to-use/manual-layout-integration.mdx Demonstrates how to manually integrate QuickLayout into a UIView subclass. This involves adding subviews using `addSubviews`, defining the layout in a `body` property, and applying the layout within `layoutSubviews` and `sizeThatFits`. ```swift import QuickLayout final class MyView: UIView { private let label = { let label = UILabel() label.text = "Hello World!" return label }() private let image = { let image = UIImageView() image.image = UIImage(systemName: "globe.americas") return image }() init() { super.init(frame: .zero) self.addSubviews { label image } } var body: Layout { HStack { label Spacer(8) image } } override func layoutSubviews() { super.layoutSubviews() body.applyFrame(bounds) } override func sizeThatFits(_ proposedSize: CGSize) { body.sizeThatFits(proposedSize) } } ``` -------------------------------- ### LayoutNode and Element Protocols Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/concepts/proposed-size.mdx Defines the basic structure for layout nodes and the protocol for elements to report their layout. This is foundational for understanding QuickLayout's sizing mechanisms. ```swift struct LayoutNode { let size: CGSize let children: [LayoutNode] } protocol Element { public func quick_layoutThatFits(_ proposedSize: CGSize) -> LayoutNode } ``` -------------------------------- ### Basic Grid Layout Structure Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/grid.mdx Demonstrates the fundamental usage of the Grid and GridRow components to create a basic two-row layout with multiple views in each row. ```swift var body: Layout { Grid { GridRow { view1 view2 view3 } GridRow { view4 view5 view6 } } } ``` -------------------------------- ### Login View Layout with Conditional Element Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/code-samples.mdx Creates a login view using QuickLayout's VStack, including conditional rendering for a 'Create Account' button based on the `keyboardShown` state. The `didSet` observer on `keyboardShown` ensures layout updates. ```swift import QuickLayout @QuickLayout class LoginView: UIView { var keyboardShown: Bool = false { didSet { createAccountButton.isHidden = keyboardShown setNeedsLayout() } } let appIconView = UIImageView() let usernameField = UITextField() let passwordField = UIButton() let logInButton = UIButton() let forgotPasswordButton = UIButton() let createAccountButton = UIButton() var body: Layout { VStack { Spacer() appIconView Spacer() Spacer(8) usernameField Spacer(8) passwordField Spacer(8) logInButton Spacer(8) forgotPasswordButton Spacer(minLength: 8) if !createAccountButton.isHidden { createAccountButton } }.padding(.horizontal: 16) } } ``` -------------------------------- ### @QuickLayout Macro Expansion for layoutSubviews and sizeThatFits Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/how-to-use/quick-layout-macro.mdx Illustrates the code generated by the @QuickLayout macro. It shows the injected implementations for `layoutSubviews` and `sizeThatFits` methods within a UIView subclass. If a custom `layoutSubviews` is provided, the macro injects its implementation. Custom `sizeThatFits` implementations are not modified by the macro. ```swift final class MyView: UIView { ... var body: Layout { ... } // -------- START OF MACRO EXPANSION --------- override func layoutSubviews() { super.layoutSubviews() _QuickLayoutViewImplementation.layoutSubviews(self) } override func sizeThatFits(_ size: CGSize) -> CGSize { _QuickLayoutViewImplementation.sizeThatFits(self, size: size) ?? .zero } // -------- END OF MACRO EXPANSION ----------- } ``` -------------------------------- ### Using @QuickLayout View in a UIViewController Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/how-to-use/manual-layout-integration-uiviewcontrollers.mdx Integrate a `@QuickLayout` marked UIView into a UIViewController. Ensure the view is added as a subview and its frame is applied within `viewDidLayoutSubviews`. ```swift @QuickLayout class MyView: UIView { var body: Layout { ... } } class ViewController: UIViewController { let myView = MyView() override func viewDidLoad() { super.viewDidLoad() view.addSubview(myView) } var body: Layout { ZStack { myView } } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() body.applyFrame(view.bounds.inset(by: view.safeAreaInsets)) } } ``` -------------------------------- ### Swift If...Else for Conditional Layout Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/condition-if-else.mdx Demonstrates how to use Swift's if-else syntax within a QuickLayout HStack to conditionally render one of two icons based on the 'somethingTrue' boolean. ```swift var body: Layout { HStack { if somethingTrue { icon1 } else { icon2 } } } ``` -------------------------------- ### Basic View Definition with QuickLayout Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/intro.mdx Define a custom UIView subclass using the @QuickLayout macro. Subviews, layout, and sizeThatFits are managed automatically. ```swift import QuickLayout @QuickLayout class MyCellView: UIView { let titleLabel = UILabel() let subtitleLabel = UILabel() var body: Layout { HStack { VStack(alignment: leading) { titleLabel Spacer(4) subtitleLabel } Spacer() } .padding(.horizontal, 16) .padding(.vertical, 8) } } ``` -------------------------------- ### VStack with Flexible Spacer Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/hstack.mdx Illustrates using a flexible Spacer() within a VStack to push views apart. ```swift var body: Layout { VStack { view1 Spacer() view2 } } ``` -------------------------------- ### Padding Extension Methods Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/padding.mdx Overview of the available padding extension methods on the Element type. ```swift extension Element { func padding(_ length: CGFloat) -> Element func padding(_ insets: EdgeInsets) -> Element func padding(_ edges: EdgeSet = .all, _ length: CGFloat) -> Element } ``` -------------------------------- ### VStack with Custom Spacing Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/vstack.mdx Illustrates how to add a fixed amount of spacing between elements in a VStack using the 'spacing' parameter. ```swift var body: Layout { VStack(spacing: 10) { label1 label2 } } ``` -------------------------------- ### LazyView Initialization and Usage Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/lazy-views.mdx Demonstrates how to define and use LazyView for conditional display of UI elements. The closure provided to LazyView is executed only when the view is first accessed in the layout. Conditional logic in the `body` prevents the view from being loaded if its condition is false. ```swift import QuickLayout @QuickLayout final class MyView: UIView { var showReplyButton: Bool = false { didSet { setNeedsLayout() } } var showDeleteButtonView: Bool = false { didSet { setNeedsLayout() } } private var replyButton = LazyView { [weak self] in /// This closure is called when the view is used in the layout for the first time. let button = UIButton(type: .system) ... return button } private var deleteButton = LazyView { [weak self] in /// This closure is called when the view is used in the layout for the first time. let button = UIButton(type: .system) ... return button } private func updateButtonStateIfNeeded(isEnabled: Bool) { /// Doesn't trigger the view load. replyButton.ifLoaded?.isEnabled = isEnabled deleteButton.ifLoaded?.isEnabled = isEnabled } var body: Layout { HStack { commentLabel if showDeleteButtonView { /// If false, the view is not loaded. deleteButton } if showReplyButton { /// If false, the view is not loaded. replyButton } } } } ``` -------------------------------- ### HFlow with Combined Spacing Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/hflow.mdx Demonstrates combining both 'itemSpacing' and 'lineSpacing' to control spacing between items and lines simultaneously. ```swift var body: Layout { HFlow(itemSpacing: 8, lineSpacing: 8) { icon label Button } } ``` -------------------------------- ### Player View Controller Layout Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/code-samples.mdx Defines the layout for a music player view controller using QuickLayout. Note that `@QuickLayout` is not yet supported for view controllers, requiring manual integration of subviews and frame application in `viewDidLoad` and `viewDidLayoutSubviews` respectively. ```swift import QuickLayout final class PlayerViewController: UIViewController { private var albumArt: UIImageView private var songTitle: UILabel private var artistName: UILabel private var currentTime: UILabel private var totalTime: UILabel private var progressBar: UIView private var progressTrack: UIView private var previousButton: UIButton private var playButton: UIButton private var nextButton: UIButton @LayoutBuilder private func layout() -> Layout { VStack { Spacer() albumArt .resizable() .aspectRatio(CGSize(width: 1, height: 1)) .padding(.horizontal, 40) Spacer(24) songTitle .padding(.horizontal, 20) Spacer(8) artistName .padding(.horizontal, 20) Spacer(32) VStack(spacing: 8) { ZStack(alignment: .leading) { progressTrack .resizable() .frame(height: 4) progressBar .resizable() .frame(width: 100, height: 4) .layoutPriority(1) } .padding(.horizontal, 20) HStack { currentTime Spacer() totalTime } .padding(.horizontal, 20) } Spacer(32) HStack(spacing: 32) { previousButton .resizable() .frame(width: 44, height: 44) playButton .resizable() .frame(width: 60, height: 60) nextButton .resizable() .frame(width: 44, height: 44) } Spacer(minLength: 24) } } // @QuickLayout is not yet supported for view controllers, so // manual layout integration is needed (we add subviews in `viewDidLoad`, // and apply frames in `viewDidLayoutSubviews`). override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor = .white self.view.addSubviews { albumArt songTitle artistName currentTime totalTime progressBar progressTrack previousButton playButton nextButton } } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() let layoutRect = view.bounds.inset(by: view.safeAreaInsets) layout().applyFrame(layoutRect) } } ``` -------------------------------- ### Define a UIView subclass with QuickLayout Source: https://github.com/facebook/quicklayout/blob/main/README.md This snippet shows how to define a UIView subclass using the @QuickLayout macro to create a declarative layout with HStacks and VStacks. ```swift import QuickLayout @QuickLayout class MyCellView: UIView { let titleLabel = UILabel() let subtitleLabel = UILabel() var body: Layout { HStack { VStack(alignment: .leading) { titleLabel Spacer(4) subtitleLabel } Spacer() } .padding(.horizontal, 16) .padding(.vertical, 8) } } ``` -------------------------------- ### Equal Width Buttons in VStack Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/ideal-layout.mdx Demonstrates using .idealLayout() on a VStack to make its children have equal width. Ensure views are marked as resizable horizontally. ```swift var body: Layout { VStack { logInButton .resizable(axis: .horizontal) Spacer(12) forgotPasswordButton .resizable(axis: .horizontal) } .idealLayout() } ``` -------------------------------- ### Basic ForEach Usage Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/condition-for-each.mdx Iterates over a collection of labels to render them within a VStack. No specific item transformations are applied. ```swift var body: Layout { VStack(spacing: 8) { ForEach(labels) } } ``` -------------------------------- ### ZStack with Top Leading Alignment Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/zstack.mdx Demonstrates how to align elements to the top leading corner within a ZStack using the 'alignment' property. ```swift var body: Layout { ZStack(alignment: .topLeading) { view1 view2 view3 } } ``` -------------------------------- ### Equal Height Labels in HStack Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/ideal-layout.mdx Shows how to achieve equal heights for elements within an HStack using .idealLayout(). Views must be marked as resizable vertically. ```swift HStack { shortTextlabel .resizable(axis: .vertical) Spacer(12) longeTextLabel .resizable(axis: .vertical) } .idealLayout() ``` -------------------------------- ### VStack with Leading Alignment Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/vstack.mdx Shows how to control the alignment of elements within a VStack using the 'alignment' parameter, setting it to '.leading'. ```swift var body: Layout { VStack(alignment: .leading) { view1 view2 view3 } } ``` -------------------------------- ### Using Expand By in a Horizontal Stack Layout Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/expandable.mdx Demonstrates how to use the '.expand(by:)' modifier on a button within an HStack to add 8x8 points of extra space around it. This centers the button with additional padding. ```swift var body: Layout { HStack { Spacer() button .expand(by: CGSize(width: 8, height: 8)) Spacer() } } ``` -------------------------------- ### FrameElement Layout Logic Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/concepts/proposed-size.mdx Demonstrates a basic Frame element that ignores the proposed size and defines its own fixed dimensions. The child element is then laid out within these fixed dimensions. ```swift struct FrameElement: Element { private let child: Element private let width: CGFloat private let height: CGFloat /// 1. The frame element ignores the proposed size /// 2. It creates a new proposed size based on its width and height. /// 3. The child is being proposed the size of the frame. /// 4. It uses width and height as it's own size. public func quick_layoutThatFits(_ proposedSize: CGSize) -> LayoutNode { let frameSize = CGSize(width: width, height: height) let childNode = child.quick_layoutThatFits(frameSize) return LayoutNode(frameSize, [childNode]) } } ``` -------------------------------- ### VStack with Fixed Spacers Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/hstack.mdx Demonstrates adding fixed spacing between views in a VStack using Spacer(value). ```swift var body: Layout { VStack { view1 Spacer(8) view2 Spacer(8) view3 } } ``` -------------------------------- ### Iterating with For Loop Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/condition-for-loop.mdx Use a for loop to iterate over a collection of labels and render each label within a VStack. ```swift var body: Layout { VStack(spacing: 8) { for label in labels { label } } } ``` -------------------------------- ### Ideal Layout Extension Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/ideal-layout.mdx Defines the extension for StackElement to include the idealLayout() method. ```swift extension StackElement { func idealLayout() -> Element } ``` -------------------------------- ### VStack with Frame Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/concepts/layout-trees.mdx Shows a VStack containing multiple color views, with a frame applied to the VStack itself. Each color view will share the VStack's width equally. ```swift /// Note: each colorView is a plain UIView. var body: Layout { VStack { colorView1 colorView2 colorView3 } .frame(width: 100, height: 100) } ``` -------------------------------- ### Constrained Size in VStack Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/constrained-size.mdx Demonstrates using constrainedSize to limit the width of a contentView to 300 points within a VStack without adding invisible padding. ```swift var body: Layout { VStack { // Limits width without adding invisible padding contentView .constrainedSize(maxWidth: 300) } } ``` -------------------------------- ### Create a nested HStack and VStack layout Source: https://github.com/facebook/quicklayout/blob/main/README.md Combine HStack and VStack to create complex layouts, such as placing an avatar next to a vertical stack of labels. Spacing is applied between elements. ```swift let avatarView = UIImage(image: avatarIcon) let label1 = UILabel(text: "Kylee Lessie") let label2 = UILabel(text: "Developer") var body: Layout { HStack(spacing: 8) { avatarView VStack(alignment: .leading, spacing: 4) { label1 label2 } } } ``` -------------------------------- ### Stateful View with Lazy Label and Layout Updates Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/how-to-use/quick-layout-macro-state-updates.mdx Demonstrates a stateful view that lazily creates a label when a button is pressed for the first time, and updates the layout accordingly using `setNeedsLayout`. ```swift import QuickLayout @QuickLayout final class CounterView: UIView { private var count = 0 private lazy var label: UILabel = { // This view will only be created when the count is set to 1 for the first time. let label = UILabel() return label }() private lazy var increaseButton: UIButton = { let button = UIButton(type: .system) button.setTitle("Increase", for: .normal) button.addTarget(self, action: #selector(addCount), for: .touchUpInside) return button }() private lazy var resetButton: UIButton = { let button = UIButton(type: .system) button.setTitle("Reset", for: .normal) button.addTarget(self, action: #selector(resetCount), for: .touchUpInside) return button }() var body: Layout { VStack(spacing: 8) { if count > 0 { label } HStack(spacing: 8) { increaseButton resetButton } } } @objc private func addCount() { count += 1 label.text = "Count: \(count)" setNeedsLayout() // <-- This is the key line. } @objc private func resetCount() { count = 0 setNeedsLayout() // <-- This is the key line. } } ``` -------------------------------- ### Apply Resizable to Image Views in HStack Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/resizable.mdx Demonstrates using the resizable modifier on an image view within an HStack to allow it to adapt its size. The first image maintains its intrinsic size, while the second is flexible. ```swift var body: Layout { HStack { faceImageView1 .frame(width: 40, height: 40) faceImageView2 .resizable() .frame(width: 40, height: 40) } } ``` -------------------------------- ### PaddingElement Layout Logic Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/concepts/proposed-size.mdx Illustrates a Padding element that adjusts the proposed size for its child by subtracting insets. The padding element's final size is determined by the child's size plus the insets. ```swift struct PaddingElement: Element { private let child: Element private let insets: UIEdgeInsets /// 1. Padding constructs a new proposed size by subtracting the /// inset from proposedSize. /// 2. The child element resolves its intrinsic size within the new proposed size. /// 3. The padding element acquires the size of the child plus the inset. public func quick_layoutThatFits(_ proposedSize: CGSize) -> LayoutNode { let newProposedSize = CGSize( width: proposedSize.width - insets.left - insets.right, height: proposedSize.height - insets.top - insets.bottom ) let childNode = child.quick_layoutThatFits(newProposedSize) let paddingSize = CGSize( width: childNode.size.width + insets.left + insets.right, height: childNode.size.height + insets.top + insets.bottom ) return LayoutNode(size: paddingSize, children: [childNode]) } } ``` -------------------------------- ### HStack with Top Alignment Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/hstack.mdx Demonstrates controlling the vertical alignment of elements within an HStack using the 'alignment' parameter. ```swift var body: Layout { HStack(alignment: .top) { view1 view2 view3 } } ``` -------------------------------- ### Grid and GridRow Function Signatures Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/grid.mdx Defines the structure and parameters for creating Grid and GridRow elements. Use Grid to establish the layout container and GridRow to define individual rows within the grid. ```swift public func Grid( alignment: Alignment = .center, horizontalSpacing: CGFloat = 0, verticalSpacing: CGFloat = 0, @FastArrayBuilder rows: () -> [GridRowElement] = { [] }, ) -> Element & Layout public func GridRow( alignment: VerticalAlignment? = nil, @FastArrayBuilder children: () -> [Element] ) -> GridRowElement ``` -------------------------------- ### Applying Fixed Size in a VStack Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/fixed-size.mdx Demonstrates how fixedSize overrides frame constraints. Use this when an element should take its natural size regardless of explicit frame dimensions. ```swift var body: Layout { VStack { label1 .frame(width: 100, height: 100) label2 .fixedSize() .frame(width: 100, height: 100) } } ``` -------------------------------- ### Nested VStacks with Frame Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/concepts/layout-trees.mdx Illustrates a VStack containing another nested VStack, both within an outer frame. This structure results in a different element tree and view sizing compared to a flat VStack. ```swift /// Note: each colorView is a plain UIView. var body: Layout { VStack { colorView1 VStack { colorView2 colorView3 } } .frame(width: 100, height: 100) } ``` -------------------------------- ### Flexible Spacer at the beginning of HStack Source: https://github.com/facebook/quicklayout/blob/main/README.md Placing a flexible Spacer at the beginning of an HStack pushes subsequent views to the trailing edge. This is useful for right-aligning content. ```swift var body: Layout { HStack { Spacer() view1 } } ``` -------------------------------- ### Padding then Frame Modifier Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/concepts/layout-trees.mdx Demonstrates applying padding before a frame modifier. The padding is applied to the colorView first, and then the frame is applied to the padded view. ```swift let colorView = UIView() var body: Layout { colorView .padding(16) .frame(width: 100, height: 100) } ``` -------------------------------- ### Enforcing Frame Size with Resizable Modifier Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/fixed-frame.mdx Demonstrates how to use the `resizable` modifier in conjunction with `frame` to ensure a view unconditionally adopts the frame's size. This is useful within an `HStack`. ```swift var body: Layout { HStack { faceImageView .resizable() .frame(width: 40, height: 40) label } } ``` -------------------------------- ### Resizable Frame for View Size Source: https://github.com/facebook/quicklayout/blob/main/README.md Make a view acquire the size of its frame by wrapping it with the resizable modifier before applying the frame. ```swift var body: Layout { imageView .resizable() .frame(width: 100, height: 100) } ``` -------------------------------- ### Swift Extension for Aspect Ratio Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/aspect-ratio.mdx Defines an extension on Element to apply an aspect ratio constraint. It takes a CGSize for the ratio and an optional ContentMode. ```swift extension Element { func aspectRatio(_ ratio: CGSize, contentMode: ContentMode = .fit) -> Element } ``` -------------------------------- ### Avoid Creating Views Directly in @QuickLayout Body Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/how-to-use/quick-layout-macro-donts.mdx Do not instantiate views directly within the `body` closure when using the @QuickLayout macro. Use layout containers and components provided by QuickLayout to build your view hierarchy. ```swift @QuickLayout final class MyView: UIView { var body: Layout { HStack { UIView() /// <-- 🛑 Don't create views in the body } } } ``` -------------------------------- ### Define Layout Priority for an Element Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/layout-priority.mdx Sets the priority for space allocation in a parent V/HStack. Default priority is 0 for even distribution. Higher priorities receive more space. ```swift extension Element { func layoutPriority(_ priority: CGFloat) -> Element } ``` -------------------------------- ### Avoid Calling `body.applyFrame()` with @QuickLayout Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/how-to-use/quick-layout-macro-donts.mdx When using the @QuickLayout macro, do not manually call `body.applyFrame()`. The macro automatically handles frame application, and manual calls can lead to double measurements and performance issues. ```swift @QuickLayout final class VerySlowView: UIView { var body: Layout { ... } /// @QuickLayout macro will insert additional /// _QuickLayoutViewImplementation call into this method. override func layoutSubviews() { super.layoutSubviews() body.applyFrame(self.bounds) /// <-- 🛑 Don't call applyFrame when using @QuickLayout macro } } ``` -------------------------------- ### EmptyLayout Function Signature Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/empty-layout.mdx This is the function signature for the EmptyLayout. It returns an Element and follows the null object pattern, sizing to zero. ```swift func EmptyLayout() -> Element ``` -------------------------------- ### Applying Offset in HStack Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/offset.mdx Demonstrates how to apply a vertical offset to a specific element within an HStack layout. Use this to adjust the position of individual items. ```swift var body: Layout { HStack { faceView1 faceView2 .offset(y: -30) faceView3 faceView4 faceView5 } } ``` -------------------------------- ### VStack Function Signature Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/vstack.mdx The function signature for VStack, showing default parameters for alignment and spacing. ```swift func VStack( alignment: HorizontalAlignment = .center, spacing: CGFloat = 0, @FastArrayBuilder children: () -> [Element] ) ``` -------------------------------- ### Stack Spacing Parameter Source: https://github.com/facebook/quicklayout/blob/main/README.md Achieve fixed spacing between views by setting the spacing parameter on the HStack. ```swift var body: Layout { HStack(spacing: 8) { view1 view2 view3 } } ``` -------------------------------- ### Swift Extension for Fixed Size Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/fixed-size.mdx Defines the fixedSize method for the Element type in Swift, allowing it to be applied to layout elements. ```swift extension Element { func fixedSize(axis: AxisSet = [.horizontal, .vertical]) -> Element } ``` -------------------------------- ### Grid with Combined Horizontal and Vertical Spacing Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/grid.mdx Applies both horizontal and vertical spacing of 8 points between rows and columns. This allows for uniform spacing throughout the grid. ```swift var body: Layout { Grid(horizontalSpacing: 8, verticalSpacing: 8) { GridRow { view1 view2 view3 } GridRow { view4 view5 view6 } } } ``` -------------------------------- ### Grid Cell Anchor Alignment with Custom UnitPoint Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/grid.mdx Positions a view within its cell using a custom UnitPoint. This allows for precise placement within the cell boundaries, overriding default alignments. ```swift var body: Layout { Grid { GridRow { view1 view2 } GridRow { view3 view4 .gridCellAnchor(UnitPoint(x: 0.5, y: 1.0)) } } } ``` -------------------------------- ### Create a VStack layout Source: https://github.com/facebook/quicklayout/blob/main/README.md Use VStack to arrange child elements vertically with specified alignment and spacing. This is useful for grouping related UI elements. ```swift let label1 = UILabel(text: "Kylee Lessie") let label2 = UILabel(text: "Developer") var body: Layout { VStack(alignment: .leading, spacing: 4) { label1 label2 } } ``` -------------------------------- ### Custom UICollectionViewCell Layout Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/code-samples.mdx Defines a reusable UICollectionViewCell with an image and text labels using QuickLayout's HStack and VStack. Ensure `setNeedsLayout()` is called to trigger layout updates. ```swift import QuickLayout @QuickLayout final class FoobarCell: UICollectionViewCell { private let imageView = UIImageView() private let titleLabel = UILabel() private let subtitleLabel = UILabel() var body: Layout { HStack(spacing: 12) { imageView .resizable() .frame(width: 60, height: 60) VStack(alignment: .leading, spacing: 4) { titleLabel subtitleLabel } Spacer() } .padding(.horizontal, 16) .padding(.vertical, 8) } func configure(image: UIImage?, title: String, subtitle: String) { imageView.image = image titleLabel.text = title subtitleLabel.text = subtitle setNeedsLayout() // Make sure this method is called to trigger the layout. } override func prepareForReuse() { super.prepareForReuse() imageView.image = nil titleLabel.text = nil subtitleLabel.text = nil } } ``` -------------------------------- ### Frame then Padding Modifier Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/concepts/layout-trees.mdx Demonstrates applying a frame modifier before padding. The frame is applied to the colorView first, and then padding is applied to the framed view. ```swift let colorView = UIView() var body: Layout { colorView .frame(width: 100, height: 100) .padding(16) } ``` -------------------------------- ### ZStack Function Signature Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/zstack.mdx The function signature for ZStack, showing its parameters for alignment and children. ```swift func ZStack( alignment: Alignment = .center, @FastArrayBuilder children: () -> [Element] ) ``` -------------------------------- ### Frame Suggestion for View Size Source: https://github.com/facebook/quicklayout/blob/main/README.md Use the frame modifier to suggest a size to a child view, positioning it within its bounds. ```swift var body: Layout { imageView .frame(width: 100, height: 100) } ``` -------------------------------- ### Fixed Spacer for Spacing Source: https://github.com/facebook/quicklayout/blob/main/README.md Use Spacer with a fixed value to create fixed space between views in a horizontal stack. ```swift var body: Layout { HStack { view1 Spacer(8) view2 Spacer(8) view3 } } ``` -------------------------------- ### Swift UIView Extension for Expandable Layout Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/expandable.mdx Defines an extension on UIView to add an 'expand(by:)' method. This method measures the view's intrinsic size and adds the specified CGSize to it. ```swift extension UIView { func expand(by size: CGSize) -> Element } ``` -------------------------------- ### HStack Function Signature Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/hstack.mdx The function signature for HStack, showing its default parameters for alignment and spacing. ```swift func HStack( alignment: VerticalAlignment = .center, spacing: CGFloat = 0, @FastArrayBuilder children: () -> [Element] ) ``` -------------------------------- ### Disabling QuickLayout with isBodyEnabled Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/how-to-use/quick-layout-macro-isBodyEnabled.mdx Override `isBodyEnabled` to conditionally disable QuickLayout. This is useful for experimentation or during migration to imperative layout. ```swift import useBaseUrl @QuickLayout final class ExperimentedView: UIView { override var isBodyEnabled: Bool { featureFlags.isQuickLayoutEnabled } init() { super.init(frame: .zero) if !isBodyEnabled { self.addSubviews { label image } } } var body: Layout { ... } override public func layoutSubviews() { super.layoutSubviews() /// Note: you don't need to call /// _QuickLayoutViewImplementation.layoutSubviews(self) /// because it's automatically injected by the macro. if !isBodyEnabled { imperativeManualLayoutSubviews() } } override public func sizeThatFits(_ size: CGSize) -> CGSize { if !isBodyEnabled { imperativeManualSizeThatFits(size) } /// OK to call for migration. _QuickLayoutViewImplementation.sizeThatFits(self, size: size) ?? .zero } } ``` -------------------------------- ### HFlow with Line Alignment Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/hflow.mdx Configures HFlow to align entire lines horizontally using the 'lineAlignment' parameter. Defaults to .center. ```swift var body: Layout { HFlow(lineAlignment: .leading) { icon label Button } } ``` -------------------------------- ### Flexible Frame Extension Signature Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/flexible-frame.mdx This is the signature for the `frame` extension on the `Element` type, defining the parameters for flexible framing. ```swift extension Element { func frame( minWidth: CGFloat? = nil, maxWidth: CGFloat? = nil, minHeight: CGFloat? = nil, maxHeight: CGFloat? = nil, alignment: Alignment = .center ) -> Element & Layout } ``` -------------------------------- ### EdgeInsets Struct Definition Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/padding.mdx Defines the structure for custom edge insets, specifying padding for top, bottom, leading, and trailing sides. ```swift struct EdgeInsets { var top: CGFloat var bottom: CGFloat var leading: CGFloat var trailing: CGFloat static let zero = EdgeInsets() init() init(top: CGFloat, leading: CGFloat, bottom: CGFloat, trailing: CGFloat) } ``` -------------------------------- ### Grid with Top Alignment Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/grid.mdx Applies top alignment to all views within the grid cells. This is the lowest priority alignment and sets the default for all elements. ```swift var body: Layout { Grid(alignment: .top) { GridRow { view1 view2 view3 } GridRow { view4 view5 view6 } } } ``` -------------------------------- ### ForEach with Item Transformation Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/condition-for-each.mdx Iterates over a collection of labels and applies a frame modifier to each item before rendering within a VStack. This is useful for applying consistent styling or constraints to each element. ```swift var body: Layout { VStack(spacing: 8) { ForEach(labels) { label in label .frame(height: 40) } } } ``` -------------------------------- ### Offset Extension Definition Source: https://github.com/facebook/quicklayout/blob/main/Sources/QuickLayout/docs/docs/layout/offset.mdx Defines the offset function for the Element type, allowing it to be extended with x and y offset values. ```swift extension Element { func offset(x: CGFloat = 0, y: CGFloat = 0) -> Element } ```