I'm learning SwiftUI, and my Profile Screen requires a view similarly shown in this image: https://i.pinimg.com/originals/1c/21/96/1c2196706b947cc9e8f656da98fd2c80.jpg
I have managed to set background and profile circular image but I'm not able to give top-right and top-left corners.
struct ProfileMainView: View {
@EnvironmentObject var profile: ProfileViewModel
@EnvironmentObject var carouselState: CarouselStateModel
@EnvironmentObject var profileManager: ProfileManager
@State var showExpose: Bool = false
@State private var editMode = false
@State private var viewMode = true
@State private var shouldDisplayProfileCreation = false
@State private var errorMessage = ""
@State private var showError = false
@EnvironmentObject var shippingAddressManager: ShippingAddressManager
@State private var authDelegate: AuthDelegate?
@State private var searchText = ""
@State private var isEditMode = false
@EnvironmentObject var userPaymentManager: UserPaymentManager
let payments = [
PayModel(number: "4444", fullname: "", source: PaymentTender.Source.visa),
PayModel(number: "1414", fullname: "", source: PaymentTender.Source.visa),
PayModel(number: "2020", fullname: "", source: PaymentTender.Source.visa)
]
let fav = ["beltBar", "beltBar"]
var body: some View {
ScrollView(.vertical, showsIndicators: false) {
VStack {
// MARK: - Top View
VStack {
ZStack {
Image("backgroundImage")
.resizable()
.frame(width: UIScreen.main.bounds.width, height: 150, alignment: .center)
.background(Color.charcoalBg)
.clipped()
.overlay(
HStack(alignment: .center) {
if showExpose {
WebImage(url: URL(string: profile.photo))
.onSuccess { image, data, cacheType in
}
.resizable()
.placeholder(Image("profilePic"))
.indicator(.activity)
.transition(.fade(duration: 0.5))
.scaledToFill()
.frame(width: 100)
.overlay(Circle().stroke(Color.white, lineWidth: 5))
.clipShape(Circle())
} else {
WebImage(url: URL(string: profile.photo))
.onSuccess { image, data, cacheType in
}
.resizable()
.placeholder(Image("profilePic"))
.indicator(.activity)
.transition(.fade(duration: 0.5))
.scaledToFill()
.frame(width: 100)
.overlay(Circle().stroke(Color.white, lineWidth: 5))
.clipShape(Circle())
}
}
.frame(height: 100, alignment: .center)
.offset(y: 75)
)
Spacer()
HStack {
Spacer()
Button {
print("notificationOnProfile button action")
} label: {
Image("notificationOnProfile")
}
}
.padding(.trailing, 30)
.padding(.top, 30)
}
}
// MARK: - Profile Name View
VStack(spacing: 5.0) {
HStack(spacing: 4.0) {
Text("Profile Name")
.font(.custom("Roboto-Medium", size: (showExpose ? 16 : 16)))
.foregroundColor(.black)
Image("star")
}
Text("Email")
.font(.custom("Roboto-Regular", size: 12))
.foregroundColor(Color.fontGrayProfile.opacity(0.6))
}
.padding(EdgeInsets(top: 45, leading: 0, bottom: 0, trailing: 0))
// MARK: - Payments View
VStack(alignment: .leading, spacing: 10) {
HStack {
Text("Payments")
.foregroundColor(Color.fontGrayProfile)
.font(.custom("Roboto-Medium", size: 14))
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.leading, 20)
.padding(.top, 14)
Button {
print("")
} label: {
Image("Pencil")
.resizable()
.frame(width: 20.0, height: 20.0)
.padding(.trailing, 22)
.padding(.top, 14)
}
}
Divider().background(Color.black.opacity(0.1))
.padding([.leading, .trailing], 20)
.padding(.bottom, 4)
VStack(alignment: .leading, spacing: 17) {
ForEach(payments) { int in
Text("int\(int.title)")
.padding(.bottom, 20)
}
}
}
.frame(maxWidth: .infinity)
.cornerRadius(14)
.background(
Rectangle()
.fill(Color.white)
.cornerRadius(14)
.shadow(
color: Color(red: 0.0/255.0, green: 0.0/255.0, blue: 0.0/255.0, opacity: 0.1),
radius: 20,
x: 0,
y: 0
)
)
.padding(EdgeInsets(top: 0, leading: 20, bottom: 20, trailing: 20))
// MARK: - Shipping Address View
VStack(alignment: .leading, spacing: 10) {
HStack {
Text("Shipping Address")
.foregroundColor(Color.fontGrayProfile)
.font(.custom("Roboto-Medium", size: 14))
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.leading, 20)
.padding(.top, 14)
Button {
print("")
} label: {
Image("Pencil")
.resizable()
.frame(width: 20.0, height: 20.0)
.padding(.trailing, 22)
.padding(.top, 14)
}
}
Divider().background(Color.black.opacity(0.1))
.padding([.leading, .trailing], 20)
.padding(.bottom, 4)
VStack(alignment: .leading, spacing: 17) {
ForEach(payments) { int in
Text("int\(int.title)")
.padding(.bottom, 20)
}
}
}
.frame(maxWidth: .infinity)
.cornerRadius(14)
.background(
Rectangle()
.fill(Color.white)
.cornerRadius(14)
.shadow(
color: Color(red: 0.0/255.0, green: 0.0/255.0, blue: 0.0/255.0, opacity: 0.1),
radius: 20,
x: 0,
y: 0
)
)
.padding(EdgeInsets(top: 0, leading: 20, bottom: 20, trailing: 20))
}
.alert(isPresented: $showError) {
Alert(title: Text(AppConstants.appName), message: Text(errorMessage), dismissButton: .default(Text("OK")))
}
.navigationBarHidden(true)
}
.edgesIgnoringSafeArea(.all)
}
}
I will Extract my Payments View and Shipping Address View later for more cleaner code and easy readability. but first I have to give top-right and top-left corner radius. (exactly shown in image) I have scrollView in an entire screen. I have gone though these link https://www.devtechie.com/community/public/posts/151937-round-specific-corners-in-swiftui but I don't understand which view to give corner radius ? Any kind of suggestion will be highly appreciated ! Thank You !