ArrangementView: Think Before You Arrange

When I first saw the ArrangementView API, something about it felt vaguely awkward, though I couldn’t quite put my finger on why. It wasn’t until I actually used it in Xcode 27.1 beta that the feeling began to take shape. After reading more of Apple’s materials and putting the API back into the context of the iPhone Duo, I realized that this discomfort came from two places. Part of it was simply that I hadn’t understood where the API was meant to fit; once I did, that part made sense. The other part came from the API itself—and remained even after I understood its design.

To use ArrangementView well, then, it helps to think one step further before reaching for it: What exactly is the relationship between the content? Which decisions can be left to the container, and which trade-offs still belong to the app? Think before you arrange.

This article is not intended as a tutorial on ArrangementView. Rather, it collects some of my observations from learning and trying to understand the API. A basic familiarity with ArrangementView will be helpful before reading.

An Unconventional Container

Unlike typical layout containers, ArrangementView is not designed simply to arrange any arbitrary pair of views. Instead, it places the relationship between two views into a set of layout rules, then combines those rules with available space, aspect ratio, size classes, and device separation regions to determine whether each view is shown and where it appears. Apple calls this mapping from inputs to layout results an arrangement.

Using it requires thinking about the API from several angles:

  • Declare relationships rather than geometry. In this respect, it is somewhat similar to NavigationSplitView. Developers declare which view is primary and which is secondary, and choose split or overlay; the container determines the actual geometry based on the environment. To anticipate the result, you first need to understand its layout and fallback rules.
  • Visibility has to be part of the content design. In a split arrangement, if the container cannot divide the available space along the specified axis, it may show only the primary view. This is not merely a layout trade-off; it is also a trade-off in terms of information and interaction. The secondary view can preserve its existing state when it reappears, but developers still need to consider how users can access the information it carries while it is temporarily hidden.
  • Configuration expresses preferences, not final outcomes. splitArrangementLayoutRatio and splitArrangementFixedLayoutSize express sizing preferences or constraints, while overlayArrangementEdge affects positioning when an overlay transitions to a side-by-side layout. These configurations are distributed across the child views, and not all of them apply to every possible arrangement result. Developers therefore need to understand not only the configurations themselves, but also how the container ultimately interprets them.

From some perspectives, ArrangementView is closer to a container such as NavigationSplitView, where adaptive behavior is already built in. The difference is that NavigationSplitView has clear navigation semantics, explicit visibility state, and established behavior when content needs to collapse—for example, it collapses into single-column stack navigation in compact width. ArrangementView, by contrast, is intended to express a broader range of content relationships, which makes its semantic anchor harder to pin down.

An Ambiguous Sense of Primary and Secondary

The trade-offs made by ArrangementView happen at the view level. When one view temporarily disappears, the issue is not merely its size, but whether its information and interactions remain accessible.

In a split arrangement, the meaning of primary is straightforward: when constraints prevent the split from being maintained, the primary view is the one that takes precedence and remains visible.

With an overlay, however, the same term takes on a different responsibility: when the container uses a layered layout, the primary view appears above the secondary view. This differs from the semantics many developers associate with the familiar overlay modifier. With that modifier, a new layer is placed on top of the original view, leaving the original view underneath. In an ArrangementView overlay, by contrast, primary refers to the upper layer.

This means that a view that naturally deserves to remain visible as the primary view in a split is not necessarily the right foreground view in an overlay.

Apple’s own example illustrates this distinction. When switching from split to overlay, it swaps the primary and secondary roles of PlayerView and UpNextView.

The problem is not that either rule is unreasonable. It is that two different sets of rules reuse the same primary/secondary terminology while asking us to assign meaning according to different relationships. Primary and secondary appear to establish a unified content relationship, but their actual meaning still depends on which arrangement is currently in use.

One Container, Two Logics

Putting split and overlay into the same container is not entirely unreasonable. When an overlay encounters an active separation region, it may itself become side by side, producing geometry that looks very similar to a split.

But similar geometry does not imply the same content relationship.

This distinction becomes especially apparent when switching between arrangements. If a product needs to move between split and overlay, developers still have to decide when the switch should happen, whether the primary and secondary roles should be exchanged, and how content state should be preserved.

In SwiftUI, .split and .overlay are different concrete types. Switching between them requires an if else, which also changes view identity. Even wrapping the selection inside a custom ArrangementViewStyle and choosing by value in makeBody is, fundamentally, just another layer around an if else; adding animation still gives you a transition rather than a continuous transformation.

I also tested updateArrangement(_:animated: true) in UIKit. Even though the container instance remains the same, the result is still a hard switch in Xcode 27.1 beta.

At least for now, there is no continuous transition between split and overlay. They have been unified under a single container, but they have not thereby become a single continuous layout state. In practice, ArrangementView feels more like an ArrangementSplitView and an ArrangementOverlayView combined into one container.

This also helps explain why the API can feel complex at first. On the surface, we are simply choosing between different arrangements within one container. In practice, we are still dealing with two different sets of content logic, along with configuration and environment values that apply only to their respective modes.

No Single Source of Truth

Once the container is responsible for deciding the final layout, a natural question follows: Can its child views know what that decision ultimately became?

Around ArrangementView, Apple provides values such as overlayArrangementZIndex, splitArrangementAxis, and reservedRegions for querying reserved regions on the device. Each serves a purpose, but they mostly expose pieces of information involved in the layout process rather than the complete result resolved by the container.

Developers can learn the axis of a split, the layering of an overlay, and the device’s reserved regions. What is much harder to answer directly is a higher-level question: What arrangement is the user actually seeing right now?

For example, an overlayArrangementZIndex value of 0 cannot by itself tell you whether the view is on the bottom layer or whether the overlay has already become side by side. Likewise, splitArrangementAxis describes the axis of the split rather than the complete visibility state. Developers can, of course, infer the answer from additional context, but doing so means that the app has to assemble these scattered signals itself.

I would rather see a centralized state resolved by the container—for example, split with its axis, overlay with its layering information, or a state in which only the primary view is currently being presented.

The important point is not whether this must literally take the form of another enum. Rather, ArrangementView currently lacks a centralized interface for expressing the final result. It gives child views several pieces of information that influence layout, but it does not directly tell them what decision the container ultimately made.

This distinction is easy to overlook in simple scenarios. Once child views need to adapt their content to the final arrangement, however, the app has to reconstruct a decision the container has already made.

ArrangementView is highly responsive to the spatial characteristics of the device, yet it does not consolidate the scenario-level decisions that a product may need. The container handles positioning for us, while the app still has to maintain content state and the semantics of each mode. As a general-purpose container, that can make it feel somewhat complex; as a specialized container, it can feel not quite centralized enough.

Its Sweet Spot Is Also Its Boundary

If ArrangementView is treated as a general-purpose container, the costs described above can easily become more pronounced. Put it on the iPhone Duo, however, and some of its seemingly unusual rules immediately gain a concrete purpose.

Folding creates new usable regions, and two related views may need to avoid the separation area while redistributing their available space. ArrangementView manages a set of rules that would be awkward to express directly with ordinary stack containers, and in this context it feels remarkably natural.

This also resolves the part of my initial discomfort that came from misunderstanding the API’s role. Some of the problems were not things the API had failed to solve; I had simply expected it to solve too much.

Finding its sweet spot, however, does not mean it should automatically be the first choice.

Apple still recommends starting with the highest-level abstraction available: standard adaptive components first, then ArrangementView, followed by reserved regions, with hinge data used only when it is genuinely necessary.

In my view, ArrangementView is worth considering when an interface genuinely needs a custom split or overlay. Before using it, I would ask a few more concrete questions:

  1. Do the two views have a stable “main content/detail” or “foreground/background” relationship?
  2. When space runs short, which view can disappear? When they overlap, which one should be on top? Can those two answers share the same primary/secondary semantics?
  3. Do the child views need only minor adjustments to accommodate the final result, or does most of the content need to identify and reconstruct the current mode itself?
  4. Does the system’s handling of fold-related regions genuinely eliminate layout decisions that the app would otherwise need to maintain?

If the answers are clear—especially when the interface already resembles one of the two relationships Apple demonstrates—ArrangementView can be a very convenient tool. If the answers are ambiguous, or if switching between those relationships is itself a core part of the product’s logic, I would rather start with HStack, VStack, ZStack, standard navigation containers, or a custom layout.

Doing so does not mean missing out on some “more advanced” approach. It simply leaves the decision in the place that understands the content best.

What makes ArrangementView feel awkward is that it wraps a very specific class of device problems inside what appears to be a general-purpose two-view container. Yet that is also where its elegance lies: once the content relationship aligns with the device rules, complexity that would otherwise belong to the app can be handed over to the system.

Think one step further before using it. Once the relationship is clear, then arrange. Think before you arrange.

Subscribe to Fatbobman

Weekly Swift & SwiftUI highlights. Join developers.

Subscribe Now