Reputation: 6190
Among the many properties of the Text
view, I couldn't find any related to text alignment. I've seen in a demo that it automatically handles RTL, and when placing stuff using View's body
, it always centers it automatically.
Is there some concept that I'm missing about layout system in SwiftUI
and if not, how can I set the text alignment properties to the Text
?
Upvotes: 384
Views: 393346
Reputation: 14380
You can do this via the modifier .multilineTextAlignment(.center)
.
Text("CENTER")
.multilineTextAlignment(.center)
Upvotes: 600
Reputation: 1181
There are multiple ways for the alignment of text in SwiftUI-
1st-
VStack(alignment: .leading){ Text("Leading alignment") }
2nd -
VStack{ Text("Leading alignment") .multilineTextAlignment(.leading) }
3rd -
VStack{ Text("Leading alignment") }.frame(maxWidth: .infinity, alignment: .leading)
And to shift the whole block of text use Spacer() under the HStack -
HStack { Text("Leading alignment") Spacer() }
Upvotes: 22
Reputation: 58533
.center
valueYou can redefine multilineTextAlignment()
method using a modified content:
import SwiftUI
extension View {
func multilineTextAlignment() -> some View {
ModifiedContent(content: self, modifier: AlignedText())
}
}
struct AlignedText : ViewModifier {
func body(content: Content) -> some View {
content
.foregroundColor(.white)
.background(.black)
.multilineTextAlignment(.center)
}
}
...and then use multilineTextAlignment()
with no explicit parameter's value.
struct ContentView : View {
var body: some View {
Text("SwiftUI SwiftUI SwiftUI SwiftUI SwiftUI")
.frame(maxWidth: .infinity, maxHeight: .infinity)
.font(.largeTitle)
.multilineTextAlignment() // Center alignment is a new DEFAULT
}
}
Upvotes: 5
Reputation: 942
You can use this property of SwiftUI
for TextAlignment.
VStack {
Text("Your Text")
.multilineTextAlignment(.center)
}
Upvotes: 1
Reputation: 111
You can always add a frame to the Text field and can modify it's alignment.
Text("Hello World!")
.frame(alignment : .topLeading)
Since, this is just for a couple of lines - this is better than using alignment on either of the Stacks
Upvotes: 10
Reputation: 1028
I had the same problem. i used this for fixing that.
Text("Test")
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading)
Upvotes: 22
Reputation:
Not sure if this is the answer you are looking for but I have experienced that SwiftUI automatically switches to RTL for languages like Arabic, you don't need to explicitly specify that like in UIKit.
Upvotes: 0
Reputation: 227
I'd like to use Spacer()
view to aligning text block.
This example show text at the trailing side:
HStack{
Spacer()
Text("Wishlist")
}
Upvotes: 14
Reputation: 20274
Was trying to understand this myself as other answers here mention Text.multilineTextAlignment(_:)
/ VStack(alignment:)
/ frame(width:alignment:)
but each solution solves a specific problem. Eventually it depends on the UI requirement and a combination of these.
VStack(alignment:)
The alignment
here is for the inner views in respective to one another.
So specifying .leading
would associate all inner views to have their leading aligned with one another.
VStack(alignment: .leading, spacing: 6) {
Text("Lorem ipsum dolor")
.background(Color.gray.opacity(0.2))
Text("sit amet")
.background(Color.gray.opacity(0.2))
}
.background(Color.gray.opacity(0.1))
.frame
In frame(width:alignment:)
or frame(maxWidth:alignment:)
, the alignment
is for the contents within the given width.
VStack(alignment: .leading, spacing: 6) {
Text("Lorem ipsum dolor")
.background(Color.gray.opacity(0.2))
Text("sit amet")
.background(Color.gray.opacity(0.2))
}
.frame(width: 380, alignment: .trailing)
.background(Color.gray.opacity(0.1))
The inners views are leading aligned respective to one another but the views themselves are trailing aligned respective to the VStack
.
.multilineTextAlignment
This specifies the alignment of the text inside and can be seen best when there are multiple lines otherwise without a defined frame(width:alignment)
, the width is automatically adjusted and gets affected by the default alignment
s.
VStack(alignment: .trailing, spacing: 6) {
Text("0. automatic frame\n+ view at parent's specified alignment\n+ multilineTA not set by default at leading")
.background(Color.gray.opacity(0.2))
Text("1. automatic frame\n+ view at parent's specified alignment\n+ multilineTA set to center")
.multilineTextAlignment(.center)
.background(Color.gray.opacity(0.2))
Text("2. automatic frame\n+ view at parent's specified alignment\n+ multilineTA set to trailing")
.multilineTextAlignment(.trailing)
.background(Color.gray.opacity(0.2))
}
.frame(width: 380, alignment: .trailing)
.background(Color.gray.opacity(0.1))
VStack(alignment: .trailing, spacing: 6) {
Text("1. automatic frame, at parent's alignment")
.background(Color.gray.opacity(0.2))
Text("2. given full width & leading alignment\n+ multilineTA at default leading")
.frame(maxWidth: .infinity, alignment: .leading)
.background(Color.gray.opacity(0.2))
Text("3. given full width & center alignment\n+ multilineTA at default leading")
.frame(maxWidth: .infinity, alignment: .center)
.background(Color.gray.opacity(0.2))
Text("4. given full width & center alignment\n+ multilineTA set to center")
.multilineTextAlignment(.center)
.frame(maxWidth: .infinity, alignment: .center)
.background(Color.gray.opacity(0.2))
Text("5. given full width & center alignment\n+ multilineTA set to trailing")
.multilineTextAlignment(.trailing)
.frame(maxWidth: .infinity, alignment: .center)
.background(Color.gray.opacity(0.2))
Text("6. given full width but no alignment\n+ multilineTA at default leading\n+ leading is based on content, looks odd sometimes as seen here")
.frame(maxWidth: .infinity)
.background(Color.gray.opacity(0.2))
}
.frame(width: 380)
.background(Color.gray.opacity(0.1))
Upvotes: 268
Reputation: 366
If you would like to keep constant width for the Text, the ".multilineTextAlignment(.leading)" won't take any effect until there is only one line of text.
This is the solution that worked for me:
struct LeftAligned: ViewModifier {
func body(content: Content) -> some View {
HStack {
content
Spacer()
}
}
}
extension View {
func leftAligned() -> some View {
return self.modifier(LeftAligned())
}
}
Usage:
Text("Hello").leftAligned().frame(width: 300)
Upvotes: 18
Reputation: 459
I've actually run into the problem where I had to align text on a single line. What I've found to work is this:
Text("some text")
.frame(alignment: .leading)
If you combine this with the frame width parameter you can get some nice text block formatting for labels and such.
Upvotes: 35
Reputation: 4512
From SwiftUI beta 3 forward, you can center a text view with the frame modifier:
Text("Centered")
.frame(maxWidth: .infinity, alignment: .center)
Upvotes: 399
Reputation: 349
We need to align the Text and not the Stack it's in. So calling multilineTextAlignment(.center)
and setting the line limits I can be able to see the texts aligned to center. I don't know why I have to set the line limits, I thought it would expand if you have a large text.
Text("blahblah")
.font(.headline)
.multilineTextAlignment(.center)
.lineLimit(50)
Upvotes: 23
Reputation: 2962
You can set alignment for Vertical stackView as leading. Like below
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
Text("Joshua Tree National Park")
.font(.subheadline)
}
Upvotes: 14
Reputation: 8952
I guess SwiftUI
wants us to use wrappers like stacks for such things.
So instead of writing something like Text("Hello World").aligned(.leading)
, the following is encouraged:
VStack(alignment: .leading) {
Text("Hello World")
}
Upvotes: 30