Text that looks off-centre, glued to one edge, or inconsistently placed can wreck a layout because SwiftUI treats Text as an intrinsically sized child and leaves alignment to its containers. The layout model means a bare Text often hugs its content and lets the parent decide placement, so wrapped lines, stack rules and modifiers like multilineTextAlignment, frame and stack alignment determine the visible result. Practical demonstrations from devgex, Ben Cardy and Hacking with Swift show the same rules in action and the same fixes work repeatedly. Try the worked examples in Hacking with Swift to see how changing multilineTextAlignment, frame alignment and stack alignment alters both the Text view bounds and the wrapped lines.
When wrapped lines appear left aligned inside a centred layout, the visible misalignment usually happens because the parent container controls placement while Text keeps its intrinsic size.
1. Reveal the Text view's true bounds
The first consequence you will see is visual, not textual: labels that look centred may be sitting inside a tiny frame that the parent has centred for them. SwiftUI expects container views to manage alignment. A plain Text without a frame will typically size to fit its content and then defer to the parent for placement. That behaviour is the source of many apparent bugs.
To diagnose this, add a visible border or background to the Text so you can see the view's actual bounds. Ben Cardy demonstrates this exact technique: a bare Text often appears centred because its small frame is being centred by the parent stack. When you draw the border you will often find the frame hugs the single line, and a multi-line label's frame can change simply with a different line break. The worked example below shows how small differences in wording move line breaks and change frames.
Worked example: place two Text views side by side in an HStack, then apply .border(Color.red) to each. If one border is narrower because of fewer words or a different break point, the two labels won't appear aligned even though the parent stack has put them on the same line. That tells you the problem is intrinsic sizing, not a mysterious bug in Text.
2. Control line alignment inside Text with multilineTextAlignment
When a Text wraps, its internal lines default to the leading edge. That means a wrapped paragraph inside a wide frame will appear left aligned even if the parent stack is centring its child. The remedy is MultilineTextAlignment, which sets how the lines inside the Text are aligned within the Text's own width. But remember: multilineTextAlignment doesn't reposition the Text view inside its parent.
It only changes how the internal lines sit inside whatever width the Text ends up with.
Hacking with Swift gives simple examples of combining multilineTextAlignment with a fixed frame width. Apply .multilineTextAlignment(.center) together with a constrained frame width to make wrapped lines centre within a known space. If you only set multilineTextAlignment without constraining the Text's width, you may still get the left aligned visual because the Text expanded to the parent width and the lines are using the default leading alignment.
Worked example: a paragraph in a VStack, given .frame(width: 300) and .multilineTextAlignment(.center), will centre each wrapped line within that 300 point area. If you remove the frame the same modifier won't produce the same visual result because the Text's reported width has changed.
3. Control the Text view's placement with frame and stack alignment
To change where the Text sits in its parent, use Frame with explicit dimensions or with flexible maximums, and pair that with the alignment parameter. A common pattern is .frame(maxWidth: .infinity, alignment: .leading) to force the Text to occupy available horizontal space and snap to an edge. Use a fixed .frame(width: 300) when you want a predictable wrap width and then choose multilineTextAlignment to decide how the lines sit inside that box.
Both devgex and Hacking with Swift show this combination repeatedly: frame defines the view's container space, then multilineTextAlignment sets the line-level alignment. The two modifiers cover most alignment needs because they address the two distinct responsibilities in SwiftUI's model: the frame controls how much space the Text is given, and multilineTextAlignment controls how text lays out inside that space.
Worked example: you have a settings screen with explanatory paragraphs. Wrap each paragraph in a container that applies .frame(maxWidth: .infinity, alignment: .leading) so every paragraph shares the same visual left edge, and then use .lineLimit or .fixedSize where you need to prevent unwanted wrapping.
4. Prefer stack-level alignment and use alignment guides for complex cases
If sibling views must line up consistently, set the alignment at the stack level. HStacks and VStacks accept an alignment parameter. For text that must line up on typographic baselines, prefer .firstTextBaseline or .lastTextBaseline. Stacks query their children for alignment anchors and baseline alignments unify Texts that use different fonts or sizes.
When those built-in alignments aren't enough, use Alignment guides. SwiftUI lets a view customise how it reports its alignment anchor using .alignmentGuide. Alignment guides are the right tool to align nonstandard edges or to create bespoke relationships between children. Hacking with Swift walks through examples where default leading or centre alignments produce poor results because children have different intrinsic sizes, and it shows how supplying a custom alignmentGuide aligns them on a shared point.
Worked example: two Text views in an HStack use different font sizes. Setting the stack to .firstTextBaseline will align their base lines even though their frames differ. If you need a different shared point, supply an alignmentGuide to both children that returns the same anchor offset.
Practical sequence to diagnose and fix alignment
Treat alignment as an ordered checklist rather than a guessing game. The same four steps repeat across tutorials and blog posts from Ben Cardy, devgex and Hacking with Swift. Follow them in order and you will find the cause quickly.
First, reveal the Text bounds with a border or background. If frames differ, the problem is intrinsic sizing and wrapping. Second, if your lines are wrapping and you want them centred or right aligned, apply .multilineTextAlignment. Third, if the whole Text needs to sit differently inside the parent, use .frame to expand or constrain the Text's available width and supply the alignment parameter you need. Fourth, if siblings must align across a stack, set the stack alignment or use baseline alignments. Use .alignmentGuide only when the built-in options don't give the desired result.
Worked scenario: two paragraph labels on a form look misaligned. You add borders and see one frame is taller because of an extra wrapped word. You constrain both with .frame(width: 300), set .multilineTextAlignment(.leading), and they align. If the text sizes differ, set the parent VStack's alignment to .firstTextBaseline and the labels will line up on their typographic baseline.
Useful modifiers and debugging tips
Several extras will save time when you hit the tricky cases. Use FixedSize to force a Text to refuse compression or expansion beyond its intrinsic size. That's handy when a Text must never wrap or when an automatic expansion creates unexpected spacing. Use LineLimit to stop wrapping where it causes frame growth you don't want.
Do not rely on .offset to fix alignment. Offsets move a view visually without changing the geometry other views see, so they create fragile layouts and confuse alignment anchors. Use alignmentGuide when you need to change how a child reports its anchor to the parent, because that changes the layout geometry in a strong way.
Remember the distinction: MultilineTextAlignment changes internal line layout, Frame changes the space the Text occupies, and stack or alignmentGuide changes how siblings line up relative to one another. The combination of those three concepts is the language of SwiftUI alignment.
When two similar labels still misalign
Slight wording differences move line breaks. Ben Cardy highlights this in his examples: two paragraphs that look like the same length can have different wrap points and so different intrinsic widths. The robust solution is to give both labels the same container width or to align them at the stack level.
If you are building forms or settings screens with multiple explanatory paragraphs, use a shared container width such as .frame(width: 300) or a full width container with .frame(maxWidth: .infinity, alignment: .leading). That gives predictable wrapping and avoids the subtle visual jitter that comes from sentence-level differences in copy.
In Short
1. Add a border to reveal whether the Text's frame hugs its content or fills space.
2. Use .multilineTextAlignment to change how wrapped lines sit inside the Text's width.
3. Use .frame with explicit width or MaxWidth: .infinity plus an alignment to place the Text inside its parent.
4. Prefer stack-level alignment or baseline alignment for consistent edges across siblings and use .alignmentGuide for bespoke alignment needs.
Related Articles
- 8 steps to keep freelancing viable as AI reshapes work
- 10 Steps to Build AI Summarisation APIs That Earn in 2026
- 6-step framework for ML system design
Download the Hacking with Swift Xcode project and run the samples while toggling multilineTextAlignment, frame alignment and stack alignments to see how each change affects the Text bounds and the wrapped lines.
This article was created with AI assistance.