How to align the right side of an object to the exact middle of a view SwiftUI - swift

I have an HStack with two Texts.
HStack {
Text("Hello")
Text("World")
}
I want Text("Hello") to be on the left side of the page and Text("World") to be on the right side of the page and for both texts to be equidistant from the exact horizontal center of the page. I added a visual for clarification:Visual
I've tried a bunch of different stuff but I haven't found any way to accomplish this task precisely.

You can use the alignment argument of the frame modifier.
Spacing argument for the HStack is for the spacing in between the texts.
HStack(spacing: 0) {
Text("Hello, World!")
.frame(maxWidth: .infinity, alignment: .trailing)
Text("Hello, World!")
.frame(maxWidth: .infinity, alignment: .leading)
}

I really didn't understand your need but according to your drawing I think you need something like below,
HStack{
Spacer()
Text("Hello")
.background(Color.orange)
Spacer().frame(width: 20)
Text("World")
.background(Color.orange)
Spacer()
}

Related

Align elements both leading and trailing in same container, without stretching it, in SwiftUI

I'm trying to build a simple chat with a design like the most usual messengers.
A message consists of a user name (if not your own message), the message itself and a timestamp.
I want the width of a message to be determined by the widest child element (most likely the message, but in rare cases maybe the user name or timestamp).
I also want the user name and message to be aligned leading/left and the timestamp to be aligned trailing/right, just like group chats in WhatsApp, Signal or the likes..
I tried weird amounts of H/V/Z-Stacks, which lead to weird happenings. I also tried both adding Spacers and maxLength = .infinity, which lead to the message stretching to the far right with lots of empty space.
My current code has all elements aligned centered:
And this is what I want:
This code is only for the comment, which itself is embedded into a ScrollView/VStack for each one.
HStack() {
if comment.author?.id == currentUserId {
Spacer()
.frame(width: 50)
Spacer()
}
VStack(spacing: 3) {
if comment.author?.id != currentUserId {
Text("Test User")
.font(.body)
.frame(alignment: .leading)
.border(.red)
}
Text("Test message content")
.frame(alignment: .leading)
.border(.red)
Text(date)
.foregroundColor(.gray)
.frame(alignment: .trailing)
.border(.red)
}
.border(.green)
.padding(10)
.background(Color.gray)
.cornerRadius(10)
if comment.author?.id != currentUserId {
Spacer()
Spacer()
.frame(width: 50)
}
}
Also I thought the double Spacers on the left or right side looked kinda weird. I tried using .frame(minWidth: 50), which ended up way too wide and pushes even a small message like the one on the image into a second line.
I'm happy for any ideas for these problems, but I'm trying to go for a simple solution and no complex calculations with alignmentGuides or GeometryReader or similar.
.frame allows you to specify the alignment.
So you could just make the VStack leading and then use .frame on the last element with alignment: .trailing. Keep in mind that the View will then grow to its available space. If you want to prevent that, just add .fixedSize() (or .fixedSize(horizontal: true, vertical: false)) to the parent view.
GroupBox {
VStack(alignment: .leading) {
Text("Test User")
Text("Test Message Content")
Text("9.5.2022, 19:31")
.font(.caption)
.foregroundColor(.secondary)
.frame(maxWidth: .infinity, alignment: .trailing)
}
.fixedSize()
}
or if you want to keep the VStack on the default alignment
GroupBox {
VStack {
Text("Test User")
.frame(maxWidth: .infinity, alignment: .leading)
Text("Test Message Content")
Text("9.5.2022, 19:31")
.font(.caption)
.foregroundColor(.secondary)
.frame(maxWidth: .infinity, alignment: .trailing)
}
.fixedSize()
}
but it also works using a HStack + Spacer
GroupBox {
VStack(alignment: .leading) {
Text("Test User")
Text("Test Message Content")
HStack {
Spacer()
Text("9.5.2022, 19:31")
.font(.caption)
.foregroundColor(.secondary)
}
}
.fixedSize()
}

SwiftUI: How to center align independent of other content in HStack?

I have an HStack with content I want left aligned and then Details title to be centered. I am using a Spacer() to try and accomplish this but it looks like it's centering Details dependent on the content to the left of it. I would like it to be independent of that and just be centered to the screen. Is that possible using Spacer()?
VStack {
HStack(alignment: .top) {
Text("<------")
Spacer()
Text("Details")
Spacer()
}
Spacer()
}
A possible approach is to use overlay, like
VStack {
HStack(alignment: .top) {
Text("<------")
Spacer()
}
.overlay(
Text("Details") // << here !!
, alignment: .top)
Spacer()
}
, depending on needs you can place it to root VStack

How to move this to the top?

I just learned how to implement specific rounded corners, but now it seems nothing will align to the top of the screen, even with spacers. How can I get it to align to the top of the screen?
Additionally, I would like the green to ignore the top safe area, but it wasn't doing that earlier either.
import SwiftUI
struct Dashboard: View {
#State var bottomLeft: CGFloat = 25
var body: some View {
ZStack {
Color("background")
.edgesIgnoringSafeArea(.all)
VStack {
VStack {
Text("Good Morning, Sarah")
.font(Font.system(size: 36))
.foregroundColor(.standaloneLabelColor)
.fontWeight(.semibold)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal)
Text("We're glad to see you and hope you're doing well. Let's take on the day.")
.font(Font.system(size: 20))
.foregroundColor(.standaloneLabelColor)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal)
.padding(.bottom)
}
.background(Color.appColor)
.cornerRadius(bottomLeft, corners: .bottomLeft)
.padding(.bottom, 10)
}
Spacer()
}
}
}
Thanks in advance.
You can set the alignment on the ZStack to .top. You can then also remove the Spacer.
A Spacer does nothing in a ZStack - since it's on its own layer. But setting the alignment on the ZStack will align all views to the top. If this is not what you want, you can also just put the Spacer in the inner VStack and the contents of that will all be aligned to the top also.
Code:
ZStack(alignment: .top) {
Color("background")
.edgesIgnoringSafeArea(.all)
VStack {
/* ... */
}
}
Also, to ignore the safe area at the top when applying the rounded corners, you should clip the corners and use ignoresSafeArea() within background. This ensures that you are only ignoring the safe area for the background, and not the whole view. Do the following:
.background(
Color.appColor
.cornerRadius(bottomLeft, corners: .bottomLeft)
.ignoresSafeArea()
)
// .background(Color.appColor)
// .cornerRadius(bottomLeft, corners: .bottomLeft)
.padding(.bottom, 10)
I had to remove some bits from your code as they were producing errors on my end. Working with what I had, you needed to add a Spacer() below the appropriate VStack.
Since your content was stored in a VStack embedded in another VStack, the outer VStack was essentially where the entire view lived. Putting a Spacer beneath this pushes it up to the top of the screen.
You can additionally add padding to the top of the VStack to move the view lower if you do not want it touching the top of the screen.
Code below:
import SwiftUI
struct ContentView: View {
#State var bottomLeft: CGFloat = 25
var body: some View {
ZStack {
Color("background")
.edgesIgnoringSafeArea(.all)
VStack {
VStack {
Text("Good Morning, Sarah")
.font(Font.system(size: 36))
.foregroundColor(Color.blue)
.fontWeight(.semibold)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal)
Text("We're glad to see you and hope you're doing well. Let's take on the day.")
.font(Font.system(size: 20))
.foregroundColor(Color.blue)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal)
.padding(.bottom)
}
.background(Color.green)
.cornerRadius(bottomLeft)
.padding(.bottom, 10)
Spacer() //Added a spacer here
}
}
}
}

How to push text to the edge in SwiftUI

I understand that this is elementary for the experienced. But please do not scold the newbie.
With arrows I showed what I want.
Here is my code
HStack {
Text("Сумма займа")
.padding()
Text("\(Int(loanAmount)) руб")
.bold()
}
Try the following:
HStack {
Text("Сумма займа")
Spacer()
Text("\(Int(loanAmount)) руб")
.bold()
}
You can also use a flexible frame.
Text("\(Int(loanAmount)) руб")
.bold()
.frame(maxWidth: .infinity, alignment: .trailing)
This expands the frame of Text to the maximum available space. It is an alternative to using Spacer in Stacks.

SwiftUI Text alignment with maxWidth not working

I have the following code:
struct ContentView: View {
var body: some View {
Text("Test")
.foregroundColor(.white)
.font(.subheadline)
.frame(maxWidth: .infinity)
.alignmentGuide(.leading) { d in d[.leading] }
.background(Color(.blue))
}
}
But as you can see on the image bellow, it does not left align the text. Does anyone knows why this is happening?
Maybe because i'm using maxWidth the alignmentGuide thinks it's already left aligned?
Because alignmentGuide has effect in container with other subviews. In this case you need to align Text within own frame.
Here is solution
Text("Test")
.foregroundColor(.white)
.font(.subheadline)
.frame(maxWidth: .infinity, alignment: .leading) // << here !!
.background(Color(.blue))