I wanted to create View with rounded corners, so I used RoundedRectangle.
VStack {
ForEach(1...10, id: \.self){_ in
ZStack(alignment: .top) {
RoundedRectangle(cornerRadius: 20)
.strokeBorder(Color(UIColor.systemGray2).opacity(0.2), lineWidth: 2)
.cornerRadius(20)
.background(Color.cell)
VStack {
Text("123123")
Text("123123")
Text("123123")
Text("123123")
Text("123123")
}
}
.padding()
}
}
.background(Color.gray)
}
But corners are not rounded in this case. How can I achieve this?
Probably you wanted something like
ZStack(alignment: .top) {
RoundedRectangle(cornerRadius: 20)
.fill(Color.cell)
RoundedRectangle(cornerRadius: 20)
.strokeBorder(Color(UIColor.systemGray2).opacity(0.2), lineWidth: 2)
VStack {
Text("123123")
Text("123123")
Related
I am trying to build a ScrollView with a conjunct of UserCard. I want a responsive view because of that the view has a GeometryReader for relative layouts but the views are superposed over themself.
this is my code:
import SwiftUI
struct UserCard: View {
let user: User
var body: some View {
GeometryReader { geometry in
VStack(alignment: .leading) {
HStack {
Image(systemName: self.user.profileImage)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: geometry.size.width * 0.1, height: geometry.size.width * 0.1)
.clipShape(Circle())
VStack(alignment: .leading) {
Text("\(self.user.name) \(self.user.surname)")
.font(.headline)
Text("UbicaciĆ³n: \(self.user.location.latitude), \(self.user.location.longitude)")
.font(.caption)
.foregroundColor(.gray)
}
.padding(.leading, 10)
}
Text("Productos")
.font(.headline)
.padding(.top, 10)
ScrollView(.horizontal) {
HStack {
ForEach(self.user.products, id: \.id) { product in
VStack {
Image(systemName: product.images.first!)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: geometry.size.width * 0.2, height: geometry.size.width * 0.2)
.cornerRadius(10)
.shadow(radius: 5)
Text(product.name)
.font(.body)
.padding(.top, 10)
Text(product.produceCategory.rawValue)
.font(.caption)
.foregroundColor(.gray)
}
.padding(.horizontal, 10)
}
}
}
}
.padding(.vertical, 20)
.padding(.horizontal, 20)
.background(Color.white)
.cornerRadius(20)
.shadow(radius: 10)
.padding(.vertical, 20)
.padding(.horizontal, 20)
}
}
}
struct ContentHomeView: View {
var body: some View {
ScrollView{
LazyVStack(spacing: 20){
ForEach(1..<100){_ in
UserCard(user: AppModelTest.user)
.padding(.vertical, 20)
}
} // LazyVStack
}
}
}
this View must look like a scrollView with individual cards showing de user info with his data but this issue I think is about GeometryReader.
I have a View stack as Expanded white part and I have given the corner radius to it, I need to give radius to only top left and top right
My Code
struct loginView: View {
#State private var stringOfTextField: String = String()
var body: some View {
ZStack {
LinearGradient(colors: [Color("primarycolor"), Color("secondarycolor")],
startPoint: .top,
endPoint: .center).ignoresSafeArea()
VStack() {
Text("Login").foregroundColor(.white).font(
.system(size: 18)
)
Image("logo")
Spacer()
}
VStack {
Spacer(minLength: 230)
VStack{
HStack {
Image(systemName: "person").foregroundColor(.gray)
TextField("Enter Email", text: $stringOfTextField)
} .padding()
.overlay(RoundedRectangle(cornerRadius: 10.0).strokeBorder(Color.gray, style: StrokeStyle(lineWidth: 1.0)))
.padding(.bottom)
TextField("Enter Password", text: $stringOfTextField)
.padding()
.overlay(RoundedRectangle(cornerRadius: 10.0).strokeBorder(Color.gray, style: StrokeStyle(lineWidth: 1.0)))
.padding(.bottom)
Text("Forgot Password ?")
.frame(maxWidth: .infinity, alignment: .trailing)
.padding(.bottom)
Button(action: {
print("sign up bin tapped")
}) {
Text("SIGN IN")
.frame(minWidth: 0, maxWidth: .infinity)
.font(.system(size: 18))
.padding()
.foregroundColor(.white)
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(Color("secondarycolor"), lineWidth: 1)
)
}
.background(Color("secondarycolor"))
.cornerRadius(25)
Spacer()
}
.padding(.vertical, 60)
.padding(.horizontal, 20)
.background(Color.white)
.cornerRadius(30)
}
}
.ignoresSafeArea(edges: [.bottom])
}
}
Preview
You can see on the end it's showing white border because border is given to all sides, I need to give it to top 2 sides only. I try by Roundedcorner, but that was not working.
You can try like this
struct ContentView: View {
var body: some View {
VStack{
//....
//your content
//.....
}
.clipShape(CustomCorner(corners: [.topLeft, .topRight], radius: 25))
}
}
struct CustomCorner: Shape {
var corners : UIRectCorner
var radius : CGFloat
func path(in rect: CGRect)->Path{
let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
return Path(path.cgPath)
}
}
I have a VStack which wraps a number elements wrapped inside another HStack, I want to add a simple bottom to top transition on load, but it does not have any effect on the output:
var body: some View {
let bottomPadding = ScreenRectHelper.shared.bottomPadding + 150
GeometryReader { geometry in
ZStack {
VisualEffectViewSUI(effect: UIBlurEffect(style: .regular))
.edgesIgnoringSafeArea(.all)
VStack(alignment: .center) {
Spacer()
HStack {
VStack(alignment: .leading, spacing: 15) {
ForEach(items, id: \.id) { item in
HStack(alignment: .center) {
Image(item.imageName)
.resizable()
.scaledToFit()
.frame(width: 24)
Spacer()
.frame(width: 15)
Text("\(item.text)")
.foregroundColor(.white)
.transition(.move(edge: .bottom))
}
.contentShape(Rectangle())
.onTapGesture {
/// Do something
}
}
}
}
.frame(width: geometry.size.width, height: nil, alignment: .center)
}.zIndex(1)
.frame(width: geometry.size.width, height: nil, alignment: .center)
.padding(.bottom, bottomPadding)
}.background(
LinearGradient(gradient: Gradient(colors: [gradientColor.opacity(0),gradientColor]), startPoint: .top, endPoint: .bottom)
)
}.edgesIgnoringSafeArea(.all)
}
This SwiftUI view is added to a UIKit view controller and that view controller is presented modally.
.transition only works if you insert something conditionally into the view.
I'm not totally sure what you want to achieve, but if you want the whole view to slide from the bottom, this would work.
struct ContentView: View {
#State private var showText = false
let bottomPadding: CGFloat = 150
var body: some View {
ZStack {
if showText { // conditional view to make .transition work
// VisualEffectViewSUI(effect: UIBlurEffect(style: .regular))
// .edgesIgnoringSafeArea(.all)
VStack(alignment: .center) {
Spacer()
HStack {
VStack(alignment: .leading, spacing: 15) {
ForEach(0 ..< 3) { item in
HStack(alignment: .center) {
Image(systemName: "\(item).circle")
.resizable()
.scaledToFit()
.frame(width: 24)
Spacer()
.frame(width: 15)
Text("Item \(item)")
.foregroundColor(.white)
}
}
}
}
}
.frame(maxWidth: .infinity)
.padding(.bottom, bottomPadding)
.background(
LinearGradient(gradient: Gradient(colors: [.blue.opacity(0), .blue]),
startPoint: .top, endPoint: .bottom)
)
.edgesIgnoringSafeArea(.all)
.transition(.move(edge: .bottom)) // here for whole modal view
}
Button("Show modal") {
withAnimation {
showText.toggle()
}
}
}
}
}
I am trying to prevent the background of my HStack from going into my safearea.
There is a ZStack that is setting the background color. I am using green just to be more defined for now.
struct AccountView: View {
var body: some View {
ZStack{
Color(.green)
.ignoresSafeArea()
VStack(spacing: 32){
HStack {
Image(systemName: "person")
.resizable()
.scaledToFill()
.frame(width: 64, height: 64)
.clipShape(Circle())
.padding(.leading)
VStack(alignment: .leading, spacing: 4) {
Text("First Last")
.font(.system(size: 18))
Text("Available")
.foregroundColor(.gray)
.font(.system(size: 14))
}
Spacer()
}
.frame(height: 80)
.background(Color("ItemBG"))
Spacer()
}
}
}
}
We need to use shape as background instead of pure-colour, then it is not spread outside.
Here is simplified demo. Tested with Xcode 13.2 / iOS 15.2
var body: some View {
VStack {
HStack {
Text("Hello")
}
.frame(maxWidth: .infinity, maxHeight: 80)
.background(Rectangle().fill(.yellow)) // << here !!
Spacer()
}
.background(Color.green.ignoresSafeArea())
}
I was able to figure it out...
I had to give by HStack a padding of 1 on the top. Apparently with IOS 15 if it touches the safe area it bleeds.
HStack {
Image(systemName: "person")
.resizable()
.scaledToFill()
.frame(width: 64, height: 64)
.clipShape(Circle())
.padding(.leading)
VStack(alignment: .leading, spacing: 4) {
Text("First Last")
.font(.system(size: 18))
Text("Available")
.foregroundColor(.gray)
.font(.system(size: 14))
}
Spacer()
}
.frame(height: 80)
.background(Color("ItemBG"))
.padding(.top, 1)
I have text on top of a rectangle through a ZStack and I was wondering if there was a way to limit the Spacer() amount within the rectangle.
ZStack{
Rectangle()
.frame(width: geometry.size.width,
height: geometry.size.height/3.25)
.shadow(radius: 5)
.foregroundColor(Color.white)
//Words ontop of the Rectangle
VStack {
HStack {
Spacer()
Text("Hello World")
}.padding(.trailing, 40)
Spacer() //<-- PROBLEM HERE
}//.offset(y: -40)
}
What It Looks Like
tl;dr:
I'd like to have is so that "Hello World", doesn't go passed the bounds of the rectangle when Spacer() is used. How can I do this? Thanks
I think what you're trying to accomplish can be achieved by just using a ZStack and specifying .topTrailing alignment:
struct ContentView: View {
var body: some View {
GeometryReader { geometry in
ZStack(alignment: .topTrailing) {
Rectangle()
.frame(height: geometry.size.height/3.25)
.shadow(radius: 5)
.foregroundColor(Color.white)
Text("Hello World")
.padding(.trailing, 40)
}
.frame(maxHeight: .infinity)
}
}
}
Alternatively:
You can forego the ZStack and make the Text an .overlay() of the Rectangle(). Here I kept your VStack and just made it an overlay which keeps it from going beyond the Rectangle.
struct ContentView: View {
var body: some View {
GeometryReader { geometry in
Rectangle()
.frame(height: geometry.size.height/3.25)
.shadow(radius: 5)
.foregroundColor(Color.white)
.overlay(
VStack {
HStack {
Spacer()
Text("Hello World")
}.padding(.trailing, 40)
Spacer()
}
)
.frame(maxHeight: .infinity)
}
}
}