VStack .leading alignment - swiftui

I can't get rid of this "leading" padding inside one of my VStacks.
I set alignment to "leading" for its parent VStack but it still shows some spacing on the left (for the text and red rounded rectangle). They were supposed to be placed on the left next to the blue edge on screenshot.
Any ideas on why this padding appears there?
Here's the code:
import SwiftUI
struct RegisterView: View {
var body: some View {
VStack(spacing: 0) {
HStack(alignment: .top) {
Text("Register")
.font(.custom("NotoSans-Regular", size: 24))
.fontWeight(.bold)
.foregroundColor(Color.tertiaryTitleColor)
}
.frame(width: 299, height: 39)
.padding(.top, 78)
HStack(spacing: 13) {
BroviderButton(imageName: "googleLogo")
BroviderButton(imageName: "facebookLogo")
}
.padding(.top, 47)
VStack(alignment: .leading, spacing: 0) {
Text("Register with E-mail")
.font(.custom("NotoSans-Regular", size: 16))
RoundedRectangle(cornerRadius: 25)
.fill(Color.red)
.frame(width: 40, height: 20)
}
.frame(width: 279)
.padding(.top, 61)
Spacer()
}
.frame(maxHeight: /*#START_MENU_TOKEN#*/.infinity/*#END_MENU_TOKEN#*/)
.frame(maxWidth: /*#START_MENU_TOKEN#*/.infinity/*#END_MENU_TOKEN#*/)
.background(Color.loginBackgroundColor)
.ignoresSafeArea()
}
}
struct RegisterView_Previews: PreviewProvider {
static var previews: some View {
RegisterView()
}
}
struct BroviderButton: View {
var imageName: String
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 27.5)
.frame(width: 133, height: 56, alignment: /*#START_MENU_TOKEN#*/.center/*#END_MENU_TOKEN#*/)
.shadow(color: Color.dropShadowColor, radius: 1, x: 10, y: 20)
.offset(y: 15)
.opacity(0.2)
.blur(radius: 20)
.opacity(0.2)
VStack {
VStack {
Image(imageName)
.resizable()
.scaledToFit()
}
.frame(height: 28, alignment: /*#START_MENU_TOKEN#*/.center/*#END_MENU_TOKEN#*/)
}
.frame(width: 133, height: 56, alignment: /*#START_MENU_TOKEN#*/.center/*#END_MENU_TOKEN#*/)
.foregroundColor(/*#START_MENU_TOKEN#*/.blue/*#END_MENU_TOKEN#*/)
.background(Color.loginBackgroundColor)
.cornerRadius(27.5)
.opacity(1)
}
}
}

You need also apply alignment to frame of container, like
VStack(alignment: .leading, spacing: 0) {
Text("Register with E-mail")
.font(.custom("NotoSans-Regular", size: 16))
RoundedRectangle(cornerRadius: 25)
.fill(Color.red)
.frame(width: 40, height: 20)
}
.frame(width: 279) // << do you really need this? why?
.frame(maxWidth: .infinity, alignment: .leading) // << here !!
.padding(.top, 61)

Related

Leave a space between the corner of the phone and the progress bar in a swiftui

I want the space progress bar between the edge of the phone to be 24. I want the size of the space to be 24. I also want the text to be aligned with the end of the bar.
my code is like this:
struct SeasonsDetailsProgressBar: View {
var bar : Float = 0.5
var body: some View {
GeometryReader{ proxy in
HStack(spacing: 22){
Text("Step")
.bold()
.font(.system(size: 12))
Spacer()
VStack(alignment: .leading){
HStack{
Text("Total steps taken")
.font(.system(size: 10))
Spacer()
Text("3.214.629 / 5.000.0000")
.font(.system(size: 10))
}
ZStack(alignment:.leading){
RoundedRectangle(cornerRadius: 4, style: .continuous)
.frame(width: proxy.size.width, height: 4)
.foregroundColor(Color.black.opacity(0.1))
RoundedRectangle(cornerRadius: 4, style: .continuous)
.frame(width: proxy.size.width * CGFloat(bar), height: 4)
.foregroundColor(Color.init(red: 0.965, green: 0.224, blue: 0.49))
}.padding(.trailing ,
proxy.size.width * 0.9)
}
}
.padding(.leading, 25)
.padding(.trailing, 25)
}
}
}
proxy.size.width gives us a width of screen you have to minus size of label and spacing between them.
struct SeasonsDetailsProgressBar: View {
var bar : Float = 0.5
var body: some View {
GeometryReader{ proxy in
HStack(spacing: 0) { // -> No spacing
Text("Step")
.bold()
.font(.system(size: 12))
.frame(width: 50, alignment: .leading) // exact width of "Step" label
.padding(.leading, 24). // exactly 24 from left side
VStack(alignment: .leading){
HStack{
Text("Total steps taken")
.font(.system(size: 10))
Spacer()
Text("3.214.629 / 5.000.0000")
.font(.system(size: 10))
.padding(.trailing, 24) // exactly 24 from left side
}
ZStack(alignment:.leading){
RoundedRectangle(cornerRadius: 4, style: .continuous)
.frame(width: (proxy.size.width - 98), height: 4) // width of screen -(24 left + 50 label + 24 right)
.foregroundColor(Color.black.opacity(0.1))
RoundedRectangle(cornerRadius: 4, style: .continuous) // width-98
.frame(width: (proxy.size.width - 98) * CGFloat(bar), height: 4)
.foregroundColor(Color.init(red: 0.965, green: 0.224, blue: 0.49))
}
}
}
} // no paddings
}
}
The problem is that you use top GeometryReader which is occupied all available space and its width is full screen width.
You need to use another GeometryReader inside your ZStack which width will be available space for your progress bar. Also you need to setup height, because otherwise it will occupied all available space like Spacer component
ZStack(alignment: .leading) {
GeometryReader { proxy in
RoundedRectangle(cornerRadius: 4, style: .continuous)
.frame(width: proxy.size.width, height: 4)
.foregroundColor(Color.black.opacity(0.1))
RoundedRectangle(cornerRadius: 4, style: .continuous)
.frame(width: proxy.size.width * CGFloat(bar), height: 4)
.foregroundColor(Color.init(red: 0.965, green: 0.224, blue: 0.49))
}.frame(height: 4)
}
And its better to use padding directly on your label and progress bar, finally it will be:
struct SeasonsDetailsProgressBar: View {
var bar : Float = 0.5
var body: some View {
HStack(spacing: 22) {
Text("Step")
.bold()
.font(.system(size: 12))
.padding(.leading, 24)
Spacer()
VStack(alignment: .leading) {
HStack{
Text("Total steps taken")
.font(.system(size: 10))
Spacer()
Text("3.214.629 / 5.000.0000")
.font(.system(size: 10))
}
ZStack(alignment:.leading) {
GeometryReader{ proxy in
RoundedRectangle(cornerRadius: 4, style: .continuous)
.frame(width: proxy.size.width, height: 4)
.foregroundColor(Color.black.opacity(0.1))
RoundedRectangle(cornerRadius: 4, style: .continuous)
.frame(width: proxy.size.width * CGFloat(bar), height: 4)
.foregroundColor(Color.init(red: 0.965, green: 0.224, blue: 0.49))
}.frame(height: 4)
}
}.padding(.trailing, 24)
}
}
}

Implementing Box-Shadow in SwiftUI

I'm trying to implement the following css code in SwiftUI
background: #FFFFFF;
box-shadow: 0px 10px 20px rgba(223, 227, 240, 0.2);
border-radius: 27.5px;
It should look like this (barely visible shadow below the button):
Here's the code i'm currently experimenting with:
import SwiftUI
struct RegisterView: View {
var body: some View {
VStack(spacing: 0) {
HStack(alignment: .top) {
Text("Register")
.font(.custom("NotoSans-Regular", size: 24))
.fontWeight(.bold)
.foregroundColor(Color.tertiaryTitleColor)
}
.frame(width: 299, height: 39)
.padding(.top, 78)
HStack {
BroviderButton(imageName: "googleLogo")
BroviderButton(imageName: "facebookLogo")
}
.padding(.top, 47)
Spacer()
}
.frame(maxHeight: .infinity)
.frame(maxWidth: .infinity)
.background(Color.loginBackgroundColor)
.ignoresSafeArea()
}
}
struct RegisterView_Previews: PreviewProvider {
static var previews: some View {
RegisterView()
}
}
struct BroviderButton: View {
var imageName: String
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 27.5)
.stroke(Color.dropShadowColor,lineWidth: 1)
.frame(width: 133, height: 56, alignment: .center)
.shadow(color: .black, radius: 2, x: 1, y: 2)
VStack {
VStack {
Image(imageName)
.resizable()
.scaledToFit()
}
.frame(height: 28, alignment: .center)
}
.frame(width: 133, height: 56, alignment: .center)
.foregroundColor(.blue)
.background(Color.loginButtonBackgroundColor)
.cornerRadius(27.5)
.opacity(1)
}
}
}
And here's how it looks like atm:
I don't understand how to translate x:10 & y:20 to SwiftUI code and also can't find the way to blur the shadow (20%). Any ideas are welcome.
Also can't figure out why that RoundedRectangle stays visible after i put VStack on top of it.. I was thinking it will hide everything but the shadow below the button.
As far as I see there are two issues here to be fixed (although of course I don't have your colors and images):
ZStack {
RoundedRectangle(cornerRadius: 27.5)
.fill(Color.dropShadowColor) // << here fill, not stroke !!
.frame(width: 133, height: 56, alignment: .center)
.shadow(color: .black, radius: 2, x: 0, y: 2) // << no offset by x
VStack {
VStack {
Image(imageName)
.resizable()
.scaledToFit()
}
.frame(height: 28, alignment: .center)
}
.frame(width: 133, height: 56, alignment: .center)
.foregroundColor(.blue)
.background(Color.loginButtonBackgroundColor) // << should be opaque color !!
.cornerRadius(27.5)
.opacity(1)
}

Force SwiftUI view to overflow in trailing direction instead of expanding in both directions

I have a SwiftUI view in an HStack that will be wider than it's parent. When this happens, the HStack expands in both leading and trailing directions, despite being put in a VStack with alignment set to .leading (which I had hoped would anchor the leading edge).
Consider the following simplified Playground code:
import SwiftUI
import PlaygroundSupport
struct TestView : View {
var body: some View {
VStack {
VStack(alignment: .leading) {
HStack {
Rectangle()
.foregroundColor(Color.red)
.frame(width: 20)
Rectangle()
.foregroundColor(.green)
}.frame(height: 40)
HStack {
Rectangle()
.foregroundColor(.orange)
.frame(width: 10)
Rectangle()
.foregroundColor(.green)
.frame(width: 200)
Rectangle()
.foregroundColor(.yellow)
.frame(width: 10)
}
.frame(height: 40)
HStack {
Rectangle()
.foregroundColor(.orange)
.frame(width: 10)
Rectangle()
.foregroundColor(.green)
.frame(width: 200)
Rectangle()
.foregroundColor(.yellow)
.frame(width: 10)
}
.frame(height: 40)
}
.border(Color.red)
}
.frame(width: 300, height: 400)
.border(Color.black)
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = UIHostingController(rootView: TestView())
In the above example, everything fits within the view and behaves as expected:
However, change the last green Rectangle to a width of 500 instead of 200, and the following happens:
You can see that the orange leading Rectangle has disappeared, pushed off to the left. Similarly, the yellow Rectangle at the end has been pushed to the right.
What I would like to have happen is have the orange Rectangle visible, meaning that all 3 HStacks would have the same x origin (0). So, the result would be seeing the orange Rectangle on the left, the green visible, but spilling over to the right, and the yellow invisible, since it would be pushed off the screen.
I assume this may have to do with using clipped() or fixedSize but I haven't been able to find a working solution yet.
The easiest solution (no workarounds or other views required) is to set the alignment in the frame modifier of the outer VStack to .leading like this:
struct TestView : View {
var body: some View {
VStack {
VStack(alignment: .leading) {
HStack {
Rectangle()
.foregroundColor(Color.red)
.frame(width: 20)
Rectangle()
.foregroundColor(.green)
}.frame(height: 40)
HStack {
Rectangle()
.foregroundColor(.orange)
.frame(width: 10)
Rectangle()
.foregroundColor(.green)
.frame(width: 200)
Rectangle()
.foregroundColor(.yellow)
.frame(width: 10)
}
.frame(height: 40)
HStack {
Rectangle()
.foregroundColor(.orange)
.frame(width: 10)
Rectangle()
.foregroundColor(.green)
.frame(width: 500)
Rectangle()
.foregroundColor(.yellow)
.frame(width: 10)
}
.frame(height: 40)
}
.border(Color.red)
}
.frame(width: 300, height: 400, alignment: .leading) //<= here
.border(Color.black)
}
}
struct TestView : View {
var body: some View {
VStack {
VStack(alignment: .leading) {
HStack {
Rectangle()
.foregroundColor(Color.red)
.frame(width: 20)
Rectangle()
.foregroundColor(.green)
}.frame(height: 40)
HStack {
Rectangle()
.foregroundColor(.orange)
.frame(width: 10)
Rectangle()
.foregroundColor(.green)
.frame(width: 200)
Rectangle()
.foregroundColor(.yellow)
.frame(width: 10)
}
.frame(height: 40)
HStack {
GeometryReader{_ in
Rectangle()
.foregroundColor(.orange)
.frame(width: 10)
.offset(x: 0)
Rectangle()
.foregroundColor(.green)
.frame(width: 500)
.offset(x: 10)
Rectangle()
.foregroundColor(.yellow)
.frame(width: 10)
.offset(x: 510)
}
}
.frame(height: 40)
}
.border(Color.red)
}
.frame(width: 300, height: 400)
.border(Color.black)
}
}

Why does the HStack make the layout render wrongly?

I'm trying to compose a view using a VStack that nests a HStack and a grid (https://github.com/spacenation/swiftui-grid). The expected outcome is that the HStack and all grid items should render. The actual outcome is that only one item of the grid renders. But when I change the HStack to VStack.The view renders as expected. Pls note that the grid renders a Geometry Reader which nests a ZStack Here's my code and an image. The blue frame in the image is the grid. It shrinked in height.
ScrollView {
VStack(spacing: 0) {
HStack {
ImageView(urlString: featuredItem.imageUrl, id: featuredItem.id)
VStack( alignment: .leading, spacing: 0) {
Text(featuredItem.title)
.padding(.vertical, 16)
.font(.custom("AbrilFatface-Regular", size: 48))
.fixedSize(horizontal: false, vertical: true)
Rectangle()
.fill(Color.red)
.frame(width: 96, height: 8)
Text(featuredItem.quote)
.font(.custom("Rubik-Regular", size: 14))
.padding(.top, 16)
.padding(.bottom, 32)
HStack {
ImageView(urlString: featuredItem.storeAvatarUrl, id:
featuredItem.id, width: 32, height: 32, isClipped: true)
Text(featuredItem.storeName)
.font(.custom("Rubik-Medium", size: 14))
}
}
.frame(width: 246)
}
.overlay(
GeometryReader { proxy in
VStack {
Text(self.featuredItem.price)
.frame(width: 72, height: 48)
}
.frame(width: proxy.size.width, height: proxy.size.height,
alignment: .topTrailing)
}
)
ShrineGrid(columns: 2, rowsHeight: .fixed(250))
}
}.edgesIgnoringSafeArea(.all)

SwiftUI ScrollView pushes the subview to leading edge of the device

I have created a screen with one top bar view and a main body view. The main body contains a registration form. As the form is too big, I have enclosed only the body part by a ScrollView. However, after doing it the form moves to the leading edge of the device. Although the form used to be in the centre of a VStack before. Could anyone please tell me what's the main issue of the ScrollView in this case?
import SwiftUI
struct HubRegistrationView: View {
var body: some View {
GeometryReader { geometry in
VStack (spacing: 0) {
VStack {
HeaderView()
}
.frame(width: geometry.size.width)
.padding()
.background(Color("B1"))
ScrollView(.vertical) {
ZStack {
Image("App Background")
.resizable()
.aspectRatio(contentMode: .fit)
.offset(y: -geometry.size.height/8)
HubFormView()
}
.frame(width: geometry.size.width)
}
}
.edgesIgnoringSafeArea(.all)
}
}
}
struct HubRegistrationView_Previews: PreviewProvider {
static var previews: some View {
Group {
HubRegistrationView()
HubRegistrationView()
.previewDevice("iPhone 8")
}
}
}
import SwiftUI
struct HubFormView: View {
#State var hubOwner: String = ""
var body: some View {
GeometryReader { geometry in
VStack {
HStack {
Text("Hub Owner")
.foregroundColor(Color("T6"))
.padding(.leading)
Text("|")
.frame(width: 1, height: 40)
.background(Color("Border1"))
TextField("00-00-2020", text: self.$hubOwner)
}
.font(.system(size: 13))
.frame(width: geometry.size.width/1.4, height: 40)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color("Border1"), lineWidth: 1)
)
HStack {
Text("Hub Name")
.foregroundColor(Color("T6"))
.padding(.leading)
Text("|")
.frame(width: 1, height: 40)
.background(Color("Border1"))
TextField("Motorcycle", text: self.$hubOwner)
}
.font(.system(size: 13))
.frame(width: geometry.size.width/1.4, height: 40)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color("Border1"), lineWidth: 1)
)
Button(action: {}) {
Text("Phone")
.foregroundColor(Color("T6"))
.padding(.leading)
Text("|")
.frame(width: 1, height: 40)
.background(Color("Border1"))
Text("Motorcycle")
.foregroundColor(Color("T5"))
Spacer()
Image(systemName: "chevron.down")
.font(.system(size: 20))
.padding(.trailing)
.foregroundColor(Color("T1"))
}
.font(.system(size: 13))
.frame(width: geometry.size.width/1.4, height: 40)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color("Border1"), lineWidth: 1)
)
Button(action: {}) {
Text("Email")
.foregroundColor(Color("T6"))
.padding(.leading)
Text("|")
.frame(width: 1, height: 40)
.background(Color("Border1"))
Text("Motorcycle")
.foregroundColor(Color("T5"))
Spacer()
Image(systemName: "chevron.down")
.font(.system(size: 20))
.padding(.trailing)
.foregroundColor(Color("T1"))
}
.font(.system(size: 13))
.frame(width: geometry.size.width/1.4, height: 40)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color("Border1"), lineWidth: 1)
)
HStack {
Text("Street")
.foregroundColor(Color("T6"))
.padding(.leading)
Text("|")
.frame(width: 1, height: 40)
.background(Color("Border1"))
TextField("Shah Makdun Ave, Uttara", text: self.$hubOwner)
}
.font(.system(size: 13))
.frame(width: geometry.size.width/1.4, height: 40)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color("Border1"), lineWidth: 1)
)
HStack {
HStack {
Text("ZIP Code")
.foregroundColor(Color("T6"))
.padding(.leading)
Text("|")
.frame(width: 1, height: 40)
.background(Color("Border1"))
TextField("1205", text: self.$hubOwner)
}
.font(.system(size: 13))
.frame(width: geometry.size.width/2.9, height: 40)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color("Border1"), lineWidth: 1)
)
Button(action: {}) {
Text("City")
.foregroundColor(Color("T6"))
.padding(.leading)
Text("|")
.frame(width: 1, height: 40)
.background(Color("Border1"))
Text("Dhaka")
.foregroundColor(Color("T5"))
Spacer()
Image(systemName: "chevron.down")
.font(.system(size: 20))
.padding(.trailing)
.foregroundColor(Color("T1"))
}
.font(.system(size: 13))
.frame(width: geometry.size.width/2.9, height: 40)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color("Border1"), lineWidth: 1)
)
}
HStack {
Text("Trade Licence")
.foregroundColor(Color("T6"))
.padding(.leading)
Text("|")
.frame(width: 1, height: 40)
.background(Color("Border1"))
TextField("Licence No.", text: self.$hubOwner)
}
.font(.system(size: 13))
.frame(width: geometry.size.width/1.4, height: 40)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color("Border1"), lineWidth: 1)
)
HStack {
Text("TIN")
.foregroundColor(Color("T6"))
.padding(.leading)
Text("|")
.frame(width: 1, height: 40)
.background(Color("Border1"))
TextField("TIN No.", text: self.$hubOwner)
}
.font(.system(size: 13))
.frame(width: geometry.size.width/1.4, height: 40)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color("Border1"), lineWidth: 1)
)
HStack {
Image(systemName: "checkmark.square.fill")
.resizable()
.frame(width: 15, height: 15)
Text("I have accepted the")
Text("terms and conditions")
.foregroundColor(Color("T2"))
Spacer()
}
.font(.system(size: 12))
.padding(.top, 10)
.frame(width: 300)
HStack {
Spacer()
Button(action: {}) {
Text("SUBMIT")
.foregroundColor(Color("T3"))
}
.padding()
.background(Color("B2"))
.cornerRadius(6)
}
.padding(.top)
.frame(width: geometry.size.width/1.4, height: 40)
}
.padding(.top, 60)
.padding(.leading, geometry.size.width/7)
}
}
}
struct HubFormView_Previews: PreviewProvider {
static var previews: some View {
HubFormView()
}
}
import SwiftUI
struct HeaderView: View {
var body: some View {
HStack {
Image("Back Icon")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 50, height: 50)
Text("HUB REGISTRATION")
.font(.system(size: 25))
.padding()
.foregroundColor(Color("T3"))
}
.padding(.top)
}
}
struct HeaderView_Previews: PreviewProvider {
static var previews: some View {
HeaderView()
}
}
thx for your code, i had to give them "real" colors so that i could see something and i got this preview now:
But how do you wanna have it?
I tested with 13.4...maybe you have an older iOS version?
ok, i tried this (because you did not show us compilable code) and it is centered...so please give us a reproducable example...
struct ContentView: View {
var body: some View {
GeometryReader { geometry in
VStack (spacing: 0) {
Spacer()
VStack {
Text("Hello")
}
.frame(width: geometry.size.width)
.padding()
.background(Color("B1"))
ScrollView(.vertical) {
ZStack {
Image("App Background")
.resizable()
.aspectRatio(contentMode: .fit)
.offset(y: -geometry.size.height/8)
Text("aha")
}
.frame(width: geometry.size.width)
}
}
.edgesIgnoringSafeArea(.all)
}
}
}