Center alignment text inside of Text in SwiftUI - swift

I am trying to set alignment on my text inside of the Text struct but I can't find any property that does that. Code example (Updated):
VStack(alignment: .center) {
Text(optionItem.title)
.fontWeight(.heavy)
.color(optionItem.color)
.font(.system(size: 64))
.frame(width: bounds.width, height: 100, alignment: .center)
.padding(.top, 60)
Text(optionItem.description)
.lineLimit(nil)
.padding([.leading, .trailing], 40)
.frame(width: bounds.width, height: 120, alignment: .center)
.font(.system(size: 16))
}
.padding(.bottom, bounds.height * 0.55)
The Text "object" is centered but not the text inside. Image:

You should use the .multilineTextAlignment(_:) method on the Text element.
This works fine for me:
Text("[...]")
.lineLimit(nil)
.multilineTextAlignment(.center)
.padding(.horizontal, 40)

Related

Format number inside image bubble

I'm having some trouble understanding how to properly align items in top of each other:
So I have the following VStack:
VStack(spacing: 0) {
Text("\(placeC.places.count)")
Image("map-pin-full-cluster-1")
.renderingMode(.template)
.resizable()
.frame(width: 35, height: 35)
.foregroundColor(.brown)
} //: END VStack
Which produces the following output:
What is the best way to have the number inside the circle? Is there a recommended SwiftUI builder that you all use that I can explore?
Typically you would use an .overlay:
Image("map-pin-full-cluster-1")
.renderingMode(.template)
.resizable()
.frame(width: 35, height: 35)
.foregroundColor(.brown)
.overlay(alignment: .top) {
Text("\(placeC.places.count)")
}
or a ZStack:
ZStack(alignment: .top) { // other alignments: .center, .bottom, .leading, .trailing
Image("map-pin-full-cluster-1")
.renderingMode(.template)
.resizable()
.frame(width: 35, height: 35)
.foregroundColor(.brown)
Text("\(placeC.places.count)")
.padding(.top, 4) // adjust this to move the text up/down
}

SwiftUI How to align the bottom of two text with different font size?

I’m trying to align the bottom of two Text but the larger one looks like thismy widget looks like this. I don’t know why there’s still some space below this Text view.
This is my code:
var body: some View {
GeometryReader{geometry in
ZStack(alignment: .center){
Image("background")
.resizable()
VStack(){
HStack(alignment: .bottom){
Text("3")
.lineLimit(1)
.font(.bold(.system(size: 100))())
.minimumScaleFactor(0.1)
.foregroundColor(Color.white)
.frame(width: nil, height: geometry.size.height/3, alignment: .bottom)
.lineLimit(1)
.shadow(radius: 2)
Text("cups")
.foregroundColor(Color.white)
.font(.system(size: 12))
.shadow(radius: 2)
}
Text("Next cup on")
.foregroundColor(Color.white)
.font(.system(size: 10))
.shadow(radius: 2)
.opacity(0.5)
Text("10 : 00")
.foregroundColor(Color.white)
.font(.system(size: 12))
.shadow(radius: 1)
.opacity(0.5)
}
}
}
}
What I want is the number 3’s bottom aligned to “cups”’s bottom.
Thanks!
Instead of .bottom, you can use .lastTextBaseline as your HStack alignment:
HStack(alignment: .lastTextBaseline) {
Text("Hello").font(.system(size: 40))
Text("World").font(.system(size: 10))
}

In SwiftUI what is an easy way to align more than one view in ZStack

I have a view and I want to add two icons to it, at top right side and at bottom right side. I managed to do that:
I used two ZStacks:
ZStack(alignment: .bottomTrailing)
{
ZStack(alignment: .topTrailing)
{
Image(item.thumbnailImage)
.clipShape(Circle())
.overlay(Circle()
.stroke(Color.gray, lineWidth: 2))
if item.isFavorite
{
Image(systemName: "star.fill")
.foregroundColor(.yellow)
.offset(x: 7, y: -7)
}
}
if item.ordered
{
Image(systemName: "checkmark.square.fill")
.offset(x: 7, y: 7)
}
}
But I have a feeling that there should be a simpler way than nesting ZStacks inside. Besides looks like the small icons don't have their x-centers aligned. I can probably fix that by changing an offset but that would make the code even more clumsy.
Is there a simpler way?
Use only one Zstack and wrap the two icons in a VStack.
ZStack(alignment: .trailing) {
Circle()
.stroke(Color.gray, lineWidth: 2)
VStack {
Image(systemName: "star.fill")
Spacer()
Image(systemName: "checkmark.square.fill")
}
// Adjust the position of star and checkmark
.offset(x: -10)
}
.frame(width: 100, height: 100)
You can use the overlay modifier, like this:
import PlaygroundSupport
import SwiftUI
PlaygroundPage.current.setLiveView(
Circle()
.strokeBorder(Color.gray, lineWidth: 6)
.frame(width: 44, height: 44)
.overlay(
Image(systemName: "star.fill")
.foregroundColor(.yellow)
.offset(x: 7, y: -7),
alignment: .topTrailing)
.overlay(
Image(systemName: "checkmark.square.fill")
.offset(x: 7, y: 7),
alignment: .bottomTrailing)
.padding()
)
If your deployment target is iOS 15 or later (or an aligned version of macOS, tvOS, or watchOS), you can use the ViewBuilder version of overlay instead:
import PlaygroundSupport
import SwiftUI
PlaygroundPage.current.setLiveView(
Circle()
.strokeBorder(Color.gray, lineWidth: 6)
.frame(width: 44, height: 44)
.overlay(alignment: .topTrailing) {
Image(systemName: "star.fill")
.foregroundColor(.yellow)
.offset(x: 7, y: -7)
}
.overlay(alignment: .bottomTrailing) {
Image(systemName: "checkmark.square.fill")
.offset(x: 7, y: 7)
}
.padding()
)
We can use lorem's suggestion to align the symbol centers using a VStack. Then we can factor out the two offset modifiers into a padding on the VStack.
import PlaygroundSupport
import SwiftUI
PlaygroundPage.current.setLiveView(
Circle()
.strokeBorder(Color.gray, lineWidth: 6)
.frame(width: 44, height: 44)
.overlay(
VStack(spacing: 0) {
Image(systemName: "star.fill")
.foregroundColor(.yellow)
Spacer()
Image(systemName: "checkmark.square.fill")
}.padding([.top, .bottom, .trailing], -7),
alignment: .trailing)
.padding()
)

SwiftUI getting SF image inside button

I have the following button and code, but cannot get the SF image to go on top of the button. I'd like it to be on the left but on top of the gradient - how do I achieve this please?
NavigationLink(destination: MyView(viewModel: FairRentViewModel(Amounts(), people: 2)))
{
Image(systemName: "person.crop.circle.badge.plus")
.font(.largeTitle)
Text("2")
.fontWeight(.bold)
.font(.title)
.padding()
.frame(minWidth: 0 maxWidth: 250, alignment: .center)
.background(gradient)
.foregroundColor(.white)
.padding(2)
.overlay(
RoundedRectangle(cornerRadius:20)
.stroke(gradient, lineWidth:15)
)
.padding(5)
}
Put it into overlay
Text("2")
.fontWeight(.bold)
.font(.title)
.padding()
.frame(minWidth: 0 maxWidth: 250, alignment: .center)
.background(gradient)
.foregroundColor(.white)
.padding(2)
.overlay(
RoundedRectangle(cornerRadius:20)
.stroke(gradient, lineWidth:15)
)
.overlay( // << here !!
Image(systemName: "person.crop.circle.badge.plus")
.font(.largeTitle)
//.padding(.leading) // might be needed
, alignment: .leading)
.padding(5)
You could try to put it inside an HStack.

SwiftUI layers in HStack

When I drag the rectangle to the left, the symbol is under the rectangle but on the right the symbol is over the rectangle, when I drag it to the right. I know, that the hierarchy of the HStack decides the layer but if I would do the right symbol over the rectangle, then both of the symbols are on the right side. I'm new at SwiftUI
HStack(spacing: 0.0){
Image(systemName: "lessthan.square")
.resizable()
.frame(width: 20.0, height: 20.0)
.padding(.leading, 30.0)
ZStack(alignment: .center) {
Group {
Rectangle()
.cornerRadius(20.0)
.frame(width: 250, height: 150)
.foregroundColor(Color(.white))
.position(rectPosition)
.shadow(radius: 5)
VStack{
Text("i")
.font(.system(size: 30))
Text("l")
.font(.system(size: 25))
}.position(rectPosition)
}.gesture(DragGesture().onChanged({ value in
self.rectPosition = CGPoint(x: value.location.x, y: 130)
}))
}
Image(systemName: "greaterthan.square")
.resizable()
.frame(width: 20.0, height: 20.0)
.padding(.trailing, 30.0)```
zIndex should help you... add it to ZStack
HStack {
Image(...)
ZStack {
...
}.zIndex(1) // << here !!
Image(...)
}