Stacking a HStack below a ZStack in SwiftUI - ios

Disclaimer: New to SwiftUI
I know a ZStack() view allows me to overlap views, which is what I want for the heading section of the app.
I set the ZStack() to not take up the entire height and had expected an HStack(), placed after the ZStack() to do just that, appear after. Instead it also overlaps with the ZStack.
I'm sure it's a simple solution to co-exist. Image and code below.
var body: some View {
GeometryReader { geometry in
ZStack(alignment: .topLeading) {
Ellipse()
.fill(self.bgColor)
.frame(width: geometry.size.width * 1.4, height: geometry.size.height * 0.28)
.position(x: geometry.size.width / 2.35, y: geometry.size.height * 0.1)
.shadow(radius: 3)
.edgesIgnoringSafeArea(.all)
HStack(alignment: .top) {
VStack(alignment: .leading) {
Text(self.title)
.font(.title)
.fontWeight(.bold)
.foregroundColor(Color.white)
Text(self.subtitle)
.font(.subheadline)
.fontWeight(.regular)
.foregroundColor(Color.white)
}
.padding(.leading, 25)
.padding(.top, 20)
Spacer()
VStack(alignment: .trailing) {
Image("SettingsIcon")
.resizable()
.scaledToFit()
.frame(width: 30, height: 30)
}
.padding(.top, 20)
.padding(.trailing, 25)
}
}
.fixedSize(horizontal: false, vertical: true)
HStack(alignment: .top) {
Text(self.title)
.font(.title)
.fontWeight(.bold)
.foregroundColor(Color.white)
}
}
}

Try the following code using a top VStack and closing the GeometryReader before the last HStack:
var body: some View {
VStack { // <-- here
GeometryReader { geometry in
ZStack(alignment: .topLeading) {
Ellipse()
.fill(self.bgColor)
.frame(width: geometry.size.width * 1.4, height: geometry.size.height * 0.28)
.position(x: geometry.size.width / 2.35, y: geometry.size.height * 0.1)
.shadow(radius: 3)
.edgesIgnoringSafeArea(.all)
HStack(alignment: .top) {
VStack(alignment: .leading) {
Text(self.title)
.font(.title)
.fontWeight(.bold)
.foregroundColor(Color.white)
Text(self.subtitle)
.font(.subheadline)
.fontWeight(.regular)
.foregroundColor(Color.white)
}
.padding(.leading, 25)
.padding(.top, 20)
Spacer()
VStack(alignment: .trailing) {
Image("SettingsIcon")
.resizable()
.scaledToFit()
.frame(width: 30, height: 30)
}
.padding(.top, 20)
.padding(.trailing, 25)
}
}.fixedSize(horizontal: false, vertical: true)
} // <-- here end GeometryReader
HStack(alignment: .top) {
Text(self.title)
.font(.title)
.fontWeight(.bold)
.foregroundColor(Color.white)
}
} // <-- here end VStack
}

Related

How do i align text to the bottom of a VStack that has a frame?

I am creating a view that is a rectangle that contains an: image, name, subtitle.
I have these in a VStack with a frame. In this VStack, the views stack correctly. However, I want the subtitle (which is text) to always be stuck to the bottom of the VStack.
At the moment the subtitle is pushed up with the other views. I tried using Spacer's but these didn't seem to do the job (maybe I used them wrong???).
Here is the view:
VStack(alignment: .center, spacing: 0) {
Image("Image")
.resizable()
.aspectRatio(contentMode: .fit)
.clipped()
.padding()
.layoutPriority(1)
}
}
Text("Name")
.font(.title2)
.fontWeight(.bold)
.foregroundColor(.black)
.minimumScaleFactor(0.5)
.multilineTextAlignment(.center)
.padding(.leading, 5)
.padding(.trailing, 5)
.padding(.bottom, 5)
Text("Subtitle")
.font(.caption)
.foregroundColor(.gray)
.lineLimit(2)
.padding(1)
}
.frame(width: 150, height: 200)
Any ideas?
Put the subtitle into an .overlay() of the VStack and use alignment: .bottom to push it to the bottom:
VStack(alignment: .center, spacing: 0) {
Image("Image")
.resizable()
.aspectRatio(contentMode: .fit)
.clipped()
.padding()
.layoutPriority(1)
Text("Name")
.font(.title2)
.fontWeight(.bold)
.foregroundColor(.black)
.minimumScaleFactor(0.5)
.multilineTextAlignment(.center)
.padding(.leading, 5)
.padding(.trailing, 5)
.padding(.bottom, 5)
}
.frame(width: 150, height: 200)
.overlay(alignment: .bottom) {
Text("Subtitle")
.font(.caption)
.foregroundColor(.gray)
.lineLimit(2)
.padding(1)
}

How do i align an image with text in an HStack?

I am trying to create a view that is a rectangle with text and images inside. This is done in a VStack. At the bottom of the VStack, I have an HStack where I have a small image and a number next to it. These need to be centred aligned but I can't seem to make that happen.
The image is higher up than the number. I need them to be at an equal height.
VStack(alignment: .center, spacing: 0) {
Image("ProductLogo")
.resizable()
.aspectRatio(contentMode: .fit)
.clipped()
.padding()
.layoutPriority(1)
Text("Text Here")
.font(.title2)
.fontWeight(.bold)
.foregroundColor(.black)
.minimumScaleFactor(0.5)
.multilineTextAlignment(.center)
.padding(.leading, 5)
.padding(.trailing, 5)
.padding(.bottom, 5)
Text("Subtitle")
.font(.headline)
.foregroundColor(.gray)
.lineLimit(2)
.padding(1)
//HERE IS WHAT NEEDS TO BE ALIGNED
HStack {
Image("CoinImage")
.resizable()
.frame(width: 35, height: 35, alignment: .center)
Text("500")
.font(.system(size: 20))
.padding(.top,20)
}
//END OF HSTACK
}
Here is an image of the VStack:
The 500 should be level with the coin image
You just need to remove padding from Text("500") and set to HStack
Please try with below code and let me know it's works for you
VStack(alignment: .center, spacing: 0) {
Image("ProductLogo")
.resizable()
.aspectRatio(contentMode: .fit)
.clipped()
.padding()
.layoutPriority(1)
Text("Text Here")
.font(.title2)
.fontWeight(.bold)
.foregroundColor(.black)
.minimumScaleFactor(0.5)
.multilineTextAlignment(.center)
.padding(.leading, 5)
.padding(.trailing, 5)
.padding(.bottom, 5)
Text("Subtitle")
.font(.headline)
.foregroundColor(.gray)
.lineLimit(2)
.padding(1)
//HERE IS WHAT NEEDS TO BE ALIGNED
HStack {
Image("CoinImage")
.resizable()
.frame(width: 35, height: 35, alignment: .center)
Text("500")
.font(.system(size: 20))
}.padding(.top, 10)
//END OF HSTACK
}

Why is there a Gap between VStacks in SwiftUI?

A whiteness is seen in the area drawn with the red line. If I change the background color of the most inclusive Vstack, that white area changes.
Deleting spacer() lines doesn't work.
Why is there a gap even though there is no space in between?
struct TabbarView: View {
var body: some View {
VStack{
Spacer()
ZStack{
Color.orange.opacity(0.5)
VStack(spacing: 0){
Text("Home")
.padding()
}
}
Spacer()
HStack{
VStack{
Image(systemName: "homekit")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: UIScreen.main.bounds.size.width / 15, height: UIScreen.main.bounds.size.height / 25)
}
}
.frame(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height / 13)
.background(Color.purple)
}
.ignoresSafeArea()
// .background(Color.purple.shadow(radius: 2))
}
}
enter image description here
you can add for VStack:
VStack {}
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .center)
updated:
struct ContentView: View {
var body: some View {
ZStack {
Color.orange.opacity(0.5)
VStack {
Spacer()
VStack(spacing: 0){
Text("Home")
.padding()
}
Spacer()
HStack {
VStack {
Image(systemName: "homekit")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 25, height: 25, alignment: .center)
.frame(width: UIScreen.main.bounds.size.width / 15, height: UIScreen.main.bounds.size.height / 25)
}
}
.frame(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height / 13)
.background(Color.purple)
}
}
.ignoresSafeArea()
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
}
}
you used nesting incorrectly and there is a native TabView for tabs
result:

Swift/SwiftUI: Background image blocks out image and text

When I use this code, the background works fine, but the other image, text and title are completely blocked out by it.
struct MainView: View {
var body: some View {
VStack(alignment: .leading, spacing: -4.0) {
Image("acdemo")
//background
.edgesIgnoringSafeArea(.all)
.blur(radius: /*#START_MENU_TOKEN#*/40.0/*#END_MENU_TOKEN#*/)
Image("acdemo")
.renderingMode(.original)
.resizable(capInsets: EdgeInsets(top: 0.0, leading: 0.0, bottom: 0.0, trailing: 0.0))
.aspectRatio(contentMode: .fit)
.frame(width: 300.0, alignment: .top)
.cornerRadius(/*#START_MENU_TOKEN#*/40.0/*#END_MENU_TOKEN#*/)
.shadow(radius: /*#START_MENU_TOKEN#*/4/*#END_MENU_TOKEN#*/)
Spacer()
.frame(height: 30)
Text("Title")
.font(.title)
.fontWeight(.bold)
.foregroundColor(Color.white)
.multilineTextAlignment(.leading)
.padding(.leading, 6.0)
.shadow(radius: /*#START_MENU_TOKEN#*/4/*#END_MENU_TOKEN#*/)
Text("Artist")
.font(.title)
.fontWeight(.regular)
.foregroundColor(Color.white)
.multilineTextAlignment(.leading)
.padding(.leading, 6.0)
.shadow(radius: /*#START_MENU_TOKEN#*/4/*#END_MENU_TOKEN#*/)
}
}
}
It's probably a very simple fix, I'm very new to Swift.
Try it like that:
struct MainView: View {
var body: some View {
ZStack {
Image("acdemo")
//background
.edgesIgnoringSafeArea(.all)
.blur(radius: /*#START_MENU_TOKEN#*/40.0/*#END_MENU_TOKEN#*/)
VStack(alignment: .leading, spacing: -4.0) {
Image("acdemo")
.renderingMode(.original)
.resizable(capInsets: EdgeInsets(top: 0.0, leading: 0.0, bottom: 0.0, trailing: 0.0))
.aspectRatio(contentMode: .fit)
.frame(width: 300.0, alignment: .top)
.cornerRadius(/*#START_MENU_TOKEN#*/40.0/*#END_MENU_TOKEN#*/)
.shadow(radius: /*#START_MENU_TOKEN#*/4/*#END_MENU_TOKEN#*/)
Spacer()
.frame(height: 30)
Text("Title")
.font(.title)
.fontWeight(.bold)
.foregroundColor(Color.white)
.multilineTextAlignment(.leading)
.padding(.leading, 6.0)
.shadow(radius: /*#START_MENU_TOKEN#*/4/*#END_MENU_TOKEN#*/)
Text("Artist")
.font(.title)
.fontWeight(.regular)
.foregroundColor(Color.white)
.multilineTextAlignment(.leading)
.padding(.leading, 6.0)
.shadow(radius: /*#START_MENU_TOKEN#*/4/*#END_MENU_TOKEN#*/)
}
}
}
}

SwiftUI issue on iOS 14 with Scrollview HStack content being cut off

I have a list of buttons that display perfectly on iOS 13 using SwiftUI, but on iOS 14 it cuts the content off where the screen ends.
Has anything changed with regards to how HStacks renders what isn't on the screen? I used to scroll and be able to see all the buttons.
I will attach some screenshots and the code.
var body: some View {
VStack(alignment: .leading, spacing: 0){
Text("Select a venue type")
.font(.custom("MavenProBold", size: 16))
.padding(.leading, 16)
.padding(.top, 18)
.foregroundColor(Color.black)
ScrollView(.horizontal, showsIndicators: false) {
HStack(alignment: .center, spacing: 4, content: {
Button(action: {
self.selectedButtonIndex = 0
})
{
VStack(alignment: .center, spacing: 0, content: {
ZStack(alignment: .bottomTrailing){
Image(systemName: "star.fill")
.frame(width: circleFrameSize, height: circleFrameSize, alignment: .center)
.font(.title)
.background(Color(hexString: "#1A88FF"))
.foregroundColor(Color.white)
.clipShape(Circle())
}
Text("Things to do")
.padding(.top, 8)
.font(.custom("MavenProBold", size: 12))
.multilineTextAlignment(.center)
.lineLimit(50)
})
.frame(width: 80, height: 80, alignment: .center)
.padding(.all, 10)
.foregroundColor(Color.black)
}
Button(action: {
self.selectedButtonIndex = 0
})
{
VStack(alignment: .center, spacing: 0, content: {
ZStack(alignment: .bottomTrailing){
Image(systemName: "star.fill")
.frame(width: circleFrameSize, height: circleFrameSize, alignment: .center)
.font(.title)
.background(Color(hexString: "#1A88FF"))
.foregroundColor(Color.white)
.clipShape(Circle())
}
Text("Things to do")
.padding(.top, 8)
.font(.custom("MavenProBold", size: 12))
.multilineTextAlignment(.center)
.lineLimit(50)
})
.frame(width: 80, height: 80, alignment: .center)
.padding(.all, 10)
.foregroundColor(Color.black)
}
Button(action: {
self.selectedButtonIndex = 0
})
{
VStack(alignment: .center, spacing: 0, content: {
ZStack(alignment: .bottomTrailing){
Image(systemName: "star.fill")
.frame(width: circleFrameSize, height: circleFrameSize, alignment: .center)
.font(.title)
.background(Color(hexString: "#1A88FF"))
.foregroundColor(Color.white)
.clipShape(Circle())
}
Text("Things to do")
.padding(.top, 8)
.font(.custom("MavenProBold", size: 12))
.multilineTextAlignment(.center)
.lineLimit(50)
})
.frame(width: 80, height: 80, alignment: .center)
.padding(.all, 10)
.foregroundColor(Color.black)
}
Button(action: {
self.selectedButtonIndex = 0
})
{
VStack(alignment: .center, spacing: 0, content: {
ZStack(alignment: .bottomTrailing){
Image(systemName: "star.fill")
.frame(width: circleFrameSize, height: circleFrameSize, alignment: .center)
.font(.title)
.background(Color(hexString: "#1A88FF"))
.foregroundColor(Color.white)
.clipShape(Circle())
}
Text("Things to do")
.padding(.top, 8)
.font(.custom("MavenProBold", size: 12))
.multilineTextAlignment(.center)
.lineLimit(50)
})
.frame(width: 80, height: 80, alignment: .center)
.padding(.all, 10)
.foregroundColor(Color.black)
}
Button(action: {
self.selectedButtonIndex = 0
})
{
VStack(alignment: .center, spacing: 0, content: {
ZStack(alignment: .bottomTrailing){
Image(systemName: "star.fill")
.frame(width: circleFrameSize, height: circleFrameSize, alignment: .center)
.font(.title)
.background(Color(hexString: "#1A88FF"))
.foregroundColor(Color.white)
.clipShape(Circle())
}
Text("Things to do")
.padding(.top, 8)
.font(.custom("MavenProBold", size: 12))
.multilineTextAlignment(.center)
.lineLimit(50)
})
.frame(width: 80, height: 80, alignment: .center)
.padding(.all, 10)
.foregroundColor(Color.black)
}
})
.padding(.leading, 8)
.padding(.trailing, 8)
.padding(.bottom, 8)
}
}
}
I also met this problem. It happens when you have a customized clipShape outside of ScrollView. By customized I mean customized Path of the shape.
From my test, when you use builtin shapes, it works fine, for example:
view.clipShape(Circle())
When you use customized shape but with builtin Path, it also works fine, for example:
view.clipShape(CustomShape())
// which CustomShape is something like:
struct CustomShape: Shape {
func path(in rect: CGRect) -> Path {
return Path(roundedRect: rect, cornerSize: CGSize(width: 10, height: 10)
}
}
But when you use a customized Path in your CustomShape, this issue happens:
view.clipShape(CustomShape())
// which CustomShape is something like:
struct CustomShape: Shape {
func path(in rect: CGRect) -> Path {
let path = UIBezierPath(roundedRect: rect,
byRoundingCorners: corners,
cornerRadii: CGSize(width: radius, height: radius))
return Path(path.cgPath)
}
}
I also tried to draw the path manually(use move, addLine, addArc), it doesn't work.
So the workaround is to use builtin Path in your customized Shape. I guess this is a bug of iOS 14, because it works fine on iOS 13.

Resources