How to pass a Buttonbar to Views - ios

I got a NavigationBar at the Bottom of some of my Views, but not all of them. It looks like this:
And I need it to refresh in every View once I change to another View since I want to implement changing the Button colors to represent which View is active at the moment.
So if the current View is Home I want it to look like this:
This is the code for the buttonbar:
struct ButtonBar: View {
#State var selection: Int? = nil
var body: some View {
HStack {
NavigationLink(destination: ShopView(), tag: 1, selection: $selection) {
Button() {
self.selection = 1
} label: {
Image("shoppingCart").resizable()
.renderingMode(.template)
.foregroundColor(selection == 1 ? Color.blue : Color(.init(red: 0.59, green: 0.62, blue: 0.67, alpha: 1)))
.frame(width: 34, height: 34)
}
}
Spacer()
NavigationLink(destination: HomeView(), tag: 2, selection: $selection) {
Button() {
self.selection = 2
} label: {
Image("home").resizable()
.renderingMode(.template)
.foregroundColor(selection == 2 ? Color.blue : Color(.init(red: 0.59, green: 0.62, blue: 0.67, alpha: 1)))
.frame(width: 34, height: 34)
}
}
Spacer()
NavigationLink(destination: MessagesView(), tag: 3, selection: $selection) {
Button() {
self.selection = 3
} label: {
Image("message").resizable()
.renderingMode(.template)
.foregroundColor(Color(.init(red: 0.59, green: 0.62, blue: 0.67, alpha: 1)))
.frame(width: 24, height: 24)
}
}
Spacer()
NavigationLink(destination: EventsView(), tag: 4, selection: $selection) {
Button() {
self.selection = 4
} label: {
Image("calender").resizable()
.renderingMode(.template)
.foregroundColor(Color(.init(red: 0.59, green: 0.62, blue: 0.67, alpha: 1)))
.frame(width: 34, height: 34)
}
}
Spacer()
NavigationLink(destination: SettingsView(), tag: 5, selection: $selection) {
Button() {
self.selection = 5
} label: {
Image("personCover").resizable()
.renderingMode(.template)
.foregroundColor(Color(.init(red: 0.59, green: 0.62, blue: 0.67, alpha: 1)))
.frame(width: 36, height: 36)
}
}
}.padding(.init(top: 0, leading: 8, bottom: 8, trailing: 8))
}
}
When I render this View in my Views like this ButtonBar() it does not refresh colors since it is created as a new View in every View. Is there a way to pass a View as an environmentObject just like with States?

Create your TabView in ContentView. There'll be three tab items: one that will lead the user to HomeView, one that will lead the user to ShopView, and another one to MessageView.Make sure to have a Navigation Link in your parent View that will lead to a child View. For example, in the code below:
import SwiftUI
struct ContentView: View {
#State private var selection = 0
var body: some View {
NavigationView {
TabView(selection: $selection){
NavigationLink(destination: HomeView()){
Text("Home Tab")
.font(.system(size: 30, weight: .bold, design: .rounded))
}
.tabItem {
Image(systemName: "house.fill")
Text("Home")
}
.tag(0)
NavigationLink(destination: ShopView()){
Text("Shop Tab")
.font(.system(size: 30, weight: .bold, design: .rounded))
}
.tabItem {
Image(systemName: "bookmark.circle.fill")
Text("Shop")
}
.tag(1)
NavigationLink(destination: MessageView()){
Text("Message Tab")
.font(.system(size: 30, weight: .bold, design: .rounded))
}
.tabItem {
Image(systemName: "message.fill")
Text("Message")
}
.tag(2)
}
.accentColor(.yellow)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Output :

Using TabView would work perfectly if I didn't need custom buttons, but this code worked for me:
import Foundation
class ViewRouter: ObservableObject {
#Published var currentPage: Page = .home
}
enum Page {
case home
case shop
case messages
case events
case settings
}
struct ContentView: View {
#StateObject var viewRouter = ViewRouter()
var body: some View {
VStack {
ZStack {
switch viewRouter.currentPage {
case .shop:
ShopView().environmentObject(loginViewController)
case .home:
HomeView()
case .messages:
MessagesView()
case .events:
EventsView()
case .settings:
SettingsView()
}
}
HStack {
Button() {
viewRouter.currentPage = .shop
} label: {
Image("shoppingCart").resizable()
.renderingMode(.template)
.foregroundColor(viewRouter.currentPage == .shop ? Color.blue : Color(.init(red: 0.59, green: 0.62, blue: 0.67, alpha: 1)))
.frame(width: 34, height: 34)
}
Spacer()
Button() {
viewRouter.currentPage = .home
} label: {
Image("home").resizable()
.renderingMode(.template)
.foregroundColor(viewRouter.currentPage == .home ? Color.blue : Color(.init(red: 0.59, green: 0.62, blue: 0.67, alpha: 1)))
.frame(width: 34, height: 34)
}
Spacer()
Button() {
viewRouter.currentPage = .messages
} label: {
Image("message").resizable()
.renderingMode(.template)
.foregroundColor(viewRouter.currentPage == .messages ? Color.blue : Color(.init(red: 0.59, green: 0.62, blue: 0.67, alpha: 1)))
.frame(width: 24, height: 24)
}
Spacer()
Button() {
viewRouter.currentPage = .events
} label: {
Image("calender").resizable()
.renderingMode(.template)
.foregroundColor(viewRouter.currentPage == .events ? Color.blue : Color(.init(red: 0.59, green: 0.62, blue: 0.67, alpha: 1)))
.frame(width: 34, height: 34)
}
Spacer()
Button() {
viewRouter.currentPage = .settings
} label: {
Image("personCover").resizable()
.renderingMode(.template)
.foregroundColor(viewRouter.currentPage == .settings ? Color.blue : Color(.init(red: 0.59, green: 0.62, blue: 0.67, alpha: 1)))
.frame(width: 36, height: 36)
}
}.padding(.init(top: 0, leading: 8, bottom: 8, trailing: 8))
}
}
}
}

Related

How to close sheet view with buttons

I'm currently running into a problem with a sheet not closing when the close button is pushed or the save button has completed transferring the data from the form to the list in homeview. Below is the code for a custom tab bar that when "New Survey" is pushed it will open the formView. The formView has two buttons closed and save. I would like it that when either one of these buttons are selected that it closes the formView.
struct FormView: View {
#Binding var surveys: [Survey]
#State var customerName = ""
#State var city = ""
#State var state = ""
#State var lineName = ""
#State var date = Date()
#Binding var isPresented: Bool
#State var showingFormView = false
var body: some View {
VStack{
ZStack {
NavigationView {
VStack {
ZStack {
Form {
Section(header: Text("Survey Info").font(.custom("Roboto-Light", size: 24)).foregroundColor(Color(red: 0.00, green: 0.188, blue: 0.42)).offset(x: -20)) { TextField("Customer Name", text: $customerName)
.padding(.vertical, 10.0)
.font(.custom("Roboto-Light", size: 18))
TextField("Customer City", text: $city)
.padding(.vertical, 10.0)
.font(.custom("Roboto-Light", size: 18))
TextField("State", text: $state)
.padding(.vertical, 10.0)
.font(.custom("Roboto-Light", size: 18))
TextField("Line Name", text: $lineName)
.padding(.vertical, 10.0)
.font(.custom("Roboto-Light", size: 18))
DatePicker("Date", selection: $date, displayedComponents: .date)
.padding(.vertical, 10.0)
.font(.custom("Roboto-Light", size: 18))
}
}
VStack (alignment: .center){
Spacer()
HStack {
**Button(action: {
self.showingFormView = false
self.isPresented = false
}, label: {
Text("Close")
.font(.custom("Roboto-Light", size: 23))
.foregroundColor(Color.white)
.frame(width: 150.0, height: 50.0, alignment: .center)
.background(Color(hue: 0.001, saturation: 0.768, brightness: 0.975))
.cornerRadius(3)
})
Button(action: {
// Save survey data to UserDefaults or any other means
let survey = Survey(customerName: customerName, city: city, state: state, lineName: lineName, date: date)
self.surveys.append(survey)
// Clear text fields
self.customerName = ""
self.city = ""
self.state = ""
self.lineName = ""
self.date = Date()
// Close FormView
self.showingFormView = false
self.isPresented = false
}, label: {
Text("Save")
.font(.custom("Roboto-Light", size: 23))
.foregroundColor(Color.white)
.frame(width: 150.0, height: 50.0, alignment: .center)
.background(Color(red: 0.451, green: 0.729, blue: 0.251))
.cornerRadius(3)
})**
}
}
}
}
.navigationBarHidden(true)
}
}
}
}
}
Custom Tab Bar
struct CustomTabBar: View {
#Binding var surveys: [Survey]
#Binding var isPresented : Bool
#State var showingFormView = false
var body: some View {
NavigationView{
VStack {
Spacer()
HStack (alignment: .bottom) {
Button {
} label: {
GeometryReader { geo in
VStack (alignment: .center, spacing: 4) {
Image(systemName: "magnifyingglass")
.resizable()
.scaledToFit()
.frame(width: 32, height: 32)
Text("Search")
.font(.custom("Roboto-Light", size: 14))
}
.frame(width: geo.size.width,height: geo.size.height)
}
}
.tint(Color(red: 0.0, green: 0.188, blue: 0.42))
**Button(action: {
showingFormView = true
}) {
GeometryReader { geo in
VStack(alignment: .center, spacing: 4) {
Image("PSIcon")
.resizable()
.scaledToFit()
.frame(width: 38, height: 38)
Text("New Survey")
.font(.custom("Roboto-Light", size: 14))
.tint(Color(red: 0.0, green: 0.188, blue: 0.42))
}
.frame(width: geo.size.width, height: geo.size.height)
}
}
.sheet(isPresented: $showingFormView) {
FormView(surveys: $surveys, isPresented: $isPresented) }
//code allows you to call up a specific view so long as a var is indicated
**
Button {
} label: {
GeometryReader { geo in
VStack (alignment: .center, spacing: 4) {
Image(systemName: "arrow.up.arrow.down")
.resizable()
.scaledToFit()
.frame(width: 35, height: 35)
Text("Sort")
.font(.custom("Roboto-Light", size: 14))
}
.frame(width: geo.size.width,height: geo.size.height)
}
}
.tint(Color(red: 0.0, green: 0.188, blue: 0.42))
}
.frame(height: 50.0)
}
}
}
}
The save button saves and creates a new item in the dynamic list but it does not close the formView. The only way for me to close the view is by swiping down on the screen.

Can't see the back button in Navigation View

For some reason I can't see the back button in the Navigation View.
I don't know if there is some extra code that I need to add in the child view but I don't know. I more or less copied the code from the tutorial, but I can't see the back button in the child view.
var body: some View {
VStack {
//Rectangle 12
Rectangle()
.fill(Color(#colorLiteral(red: 0.7137255072593689, green: 0.10196077823638916, blue: 0.10196077823638916, alpha: 1)))
.frame(width: .infinity, height: 50)
.padding(.bottom, 0.0)
NavigationView {
ZStack{
Color(red: 0.9, green: 0.9, blue: 0.9).edgesIgnoringSafeArea(.all)
ScrollView(.vertical, showsIndicators: true) {
HStack{
Text("Marketplace").font(.custom("Arial", size: 35))
.fontWeight(.medium)
.foregroundColor(Color(red: 0.1, green: 0.1, blue: 0.1))
.padding(EdgeInsets(top: 15, leading: 20, bottom: -2, trailing: 0))
Spacer()
}
ForEach(produitsdfsdf, id: \.id ) { product in
NavigationLink(destination: TempView()) {
LandingPresets.listItem(name: product.name, description: product.price, rate: product.category)
}
}
}
.navigationBarHidden(true)
}
}
.padding(.top, -8.0)
}.ignoresSafeArea(edges: .top)
.onAppear {
ProductAPI().getAllProducts {(productArr) in
self.produitsdfsdf = productArr
}
}
}
It is because of you use .navigationBarHidden(true) in main View.
You could add .navigationBarTitleDisplayMode(.inline) to your TempView().
If you give code of TempView, I'll be able to show to which part of code.

Xcode Preview canvas different then Simulator

I am currently developing an app, and I am trying to setup the Views to be accurate for different screen sizes. I get the design to what I would like in the preview, but then when I run it in the simulator some things are a little off. To note not all screens do this, just a few. Any reason why this may be?
Screenshot for reference: Xcode/Simulator Screenshot
ContentView:
struct ContentView: View {
//Removed variables for checking log ins and loading screen animation
var body: some View {
VStack{
//Check if logged in and not first time
if status && !firstTime{
ZStack{
NavigationView{
TabView(){
Tab1View()
.environmentObject(ContentViewModel())
Tab2View()
.environmentObject(ContentViewModel())
}
.navigationBarHidden(true)
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
}
ZStack{
//LoadingScreen
}
.ignoresSafeArea(edges: .all)
.onAppear(perform: animateSplash)
.opacity(endSplash ? 0 : 1)
}
}
//Check if logged and first time
else if status && firstTime{
ZStack{
NavigationView{
if role == "owner"{
WelcomeView()
} else {
WelcomeEmployeeView()
}
}
}
} else {
NavigationView{
//View in the screenshot
CreateView()
}
}
}
CreateView:
import SwiftUI
import FirebaseAuth
struct CreateView: View {
#EnvironmentObject var model: ContentViewModel
#State var companyName = ""
#State var employeeName = ""
#State var phoneNumber = ""
#State var show = false
#State var message = ""
#State var alert = false
#State var ID = ""
#State var test = ""
#State var role = "owner"
var body: some View {
ZStack{
ZStack(alignment: .topTrailing){
Path{ path in
path.move(to: CGPoint(x: 500, y: 0))
path.addLine(to: CGPoint(x: 0, y: 0))
path.addLine(to: CGPoint(x: 0, y: 80))
path.addLine(to: CGPoint(x:500, y: 180))
}
.fill(LinearGradient(gradient:Gradient(colors: [Color(#colorLiteral(red: 0.6470588235, green: 0.8196078431, blue: 0.7450980392, alpha: 1)), Color(#colorLiteral(red: 0.2549019608, green: 0.7607843137, blue: 0.8588235294, alpha: 1)), .white, .green]), startPoint: .topLeading, endPoint: .bottomTrailing))
.edgesIgnoringSafeArea(.top)
Image("icon-white")
.resizable()
.frame(width: 50, height: 60)
.padding(.top)
.padding(.trailing, 30)
}
VStack(alignment: .leading){
Text("Create a")
.foregroundColor(Color(#colorLiteral(red: 0.2549019608, green: 0.7607843137, blue: 0.8588235294, alpha: 1)))
.font(.custom("Poppins-Medium", size: 30))
Text("Company Account")
.foregroundColor(Color(#colorLiteral(red: 0.2549019608, green: 0.7607843137, blue: 0.8588235294, alpha: 1)))
.font(.custom("Poppins-Medium", size: 30))
.padding(.bottom, 30)
Text("Company Name")
.foregroundColor(Color(#colorLiteral(red: 0.2549019608, green: 0.7607843137, blue: 0.8588235294, alpha: 1)))
.font(.custom("Poppins-Semibold", size: 16))
TextField("", text: $companyName)
.frame(width: 290)
.padding(14)
.overlay(RoundedRectangle(cornerRadius: 5.0).strokeBorder(Color.black, style: StrokeStyle(lineWidth: 0.5)))
.padding(.bottom)
Text("Employee Name")
.foregroundColor(Color(#colorLiteral(red: 0.2549019608, green: 0.7607843137, blue: 0.8588235294, alpha: 1)))
.font(.custom("Poppins-Semibold", size: 16))
TextField("", text: $employeeName)
.frame(width: 290)
.padding(14)
.overlay(RoundedRectangle(cornerRadius: 5.0).strokeBorder(Color.black, style: StrokeStyle(lineWidth: 0.5)))
.padding(.bottom)
Text("Phone Number")
.foregroundColor(Color(#colorLiteral(red: 0.2549019608, green: 0.7607843137, blue: 0.8588235294, alpha: 1)))
.font(.custom("Poppins-Semibold", size: 16))
TextField("", text: $phoneNumber)
.frame(width: 290)
.padding(14)
.overlay(RoundedRectangle(cornerRadius: 5.0).strokeBorder(Color.black, style: StrokeStyle(lineWidth: 0.5)))
.padding(.bottom)
VStack(alignment: .center){
NavigationLink(
destination: VerifcationView(show: $show, ID: $ID, name: $employeeName, companyName: $companyName, phoneNumber: $phoneNumber, hasCode: $test, role: $role), isActive: $show){
ZStack{
RoundedRectangle(cornerRadius: 5)
.foregroundColor(Color(#colorLiteral(red: 0.2549019608, green: 0.7607843137, blue: 0.8588235294, alpha: 1)))
.frame(width: 315,height: 50)
Button(action: {
PhoneAuthProvider.provider().verifyPhoneNumber( "+"+self.phoneNumber, uiDelegate:nil){ (ID, error) in
if error != nil {
self.message = (error?.localizedDescription)!
self.alert.toggle()
return
}
self.ID = ID!
self.show.toggle()
}
}, label: {
Text("Create Account")
.font(.custom("Poppins-Medium", size: 18))
.foregroundColor(.white)
})
}
}
NavigationLink(
destination: JoinView()){
Text("Join as Employee")
.foregroundColor(Color(red: 141/255, green: 141/255, blue: 141/255))
.underline(/*#START_MENU_TOKEN#*/true/*#END_MENU_TOKEN#*/, color: Color(red: 141/255, green: 141/255, blue: 141/255))
}
}
.padding(.top)
}
.padding(.top)
}
.navigationBarBackButtonHidden(true)
}
}
For SwiftUI previews, you just preview a single view - CreateView. This is the only view that gets previewed. Meanwhile, your simulator runs the entire app, starting all the way back from your ContentView.
Note that inside ContentView, you're wrapping CreateView in a NavigationView.
NavigationView{
// View in the screenshot
CreateView()
}
This will add a gap at the top of the screen, pushing everything else down (resulting in the difference that you see). Even the icon-white image is pushed down into the white part of the screen, which is why you can't see it in the simulator.

UserDefaults Text / SwiftUI

When I click the "Update" button, I want the text view to save the text used in the User Defaults.
I could not. Do you know how? Can you edit the codes?
After updating, I want the checkbox to appear, but first I need to set user defaults.
Struct ContentView: View{
#State private var profilName = ""
#State private var profilSurname = ""
var body: some View{
ZStack{
VStack{
TextField("Name", text: $profilName)
.frame(height: 60)
.padding([.leading, .trailing], 20)
.foregroundColor(.white)
.font(Font.system(size: 30, design: .default))
.multilineTextAlignment(.center)
.accentColor(Color.white)
.overlay(RoundedRectangle(cornerRadius:30)
.stroke(Color(#colorLiteral(red: 0.5411764706, green:
0.4549019608, blue: 0.2823529412, alpha: 1)), lineWidth: 1)).padding(.horizontal, 50)
TextField("Surname", text: $profilSurname)
.frame(height: 60)
.padding([.leading, .trailing], 20)
.foregroundColor(.white)
.font(Font.system(size: 30, design: .default))
.multilineTextAlignment(.center)
.accentColor(Color.white)
.overlay(RoundedRectangle(cornerRadius:30)
.stroke(Color(#colorLiteral(red: 0.5411764706, green: 0.4549019608, blue: 0.2823529412, alpha: 1)), lineWidth: 1)).padding(.horizontal, 50)
Button(action: {
}, label: {
Text("Update")
.frame(width:300 , height: 40)
.padding(10)
.font(Font.system(size: 30, weight: .medium, design: .serif))
.foregroundColor(.white)
.background(RoundedRectangle(cornerRadius: 45))
.foregroundColor(.init(red: 45 / 255, green: 0 / 255, blue: 112 / 255))
})
}
}
}
}
You can save textfield content by simply calling user defaults in button action
Button(action: {
UserDefaults.standard.set(profilSurname, forKey: "Key")
}
To retrieve text from user defaults when app starts load user defaults data in init function like below
struct ContentView: View{
#State private var profilName = ""
#State private var profilSurname = ""
init() {
self._profilSurname = State(initialValue: UserDefaults.standard.object(forKey: "Key") as? String ?? "")
}
var body: some View{
struct ContentView: View{
#State private var profilName = ""
#State private var profilSurname: String = UserDefaults.standard.string(forKey: "Key") ?? ""
var body: some View{
ZStack{
VStack{
TextField("Name", text: $profilName)
.frame(height: 60)
.padding([.leading, .trailing], 20)
.foregroundColor(.black)
.font(Font.system(size: 30, design: .default))
.multilineTextAlignment(.center)
.accentColor(Color.white)
.overlay(RoundedRectangle(cornerRadius:30)
.stroke(Color(#colorLiteral(red: 0.5411764706, green:
0.4549019608, blue: 0.2823529412, alpha: 1)), lineWidth: 1)).padding(.horizontal, 50)
TextField("Surname", text: $profilSurname)
.frame(height: 60)
.padding([.leading, .trailing], 20)
.font(Font.system(size: 30, design: .default))
.multilineTextAlignment(.center)
.accentColor(Color.white)
.overlay(RoundedRectangle(cornerRadius:30)
.stroke(Color(#colorLiteral(red: 0.5411764706, green: 0.4549019608, blue: 0.2823529412, alpha: 1)), lineWidth: 1)).padding(.horizontal, 50)
Button(action: {
UserDefaults.standard.set(profilSurname, forKey: "Key")
}, label: {
Text("Update")
.frame(width:300 , height: 40)
.padding(10)
.font(Font.system(size: 30, weight: .medium, design: .serif))
.foregroundColor(.white)
.background(RoundedRectangle(cornerRadius: 45))
.foregroundColor(.init(red: 45 / 255, green: 0 / 255, blue: 112 / 255))
})
}
}
}
}
This will be the updated code.
Button(action: {
// This is the action section. You can add your code here
UserDefaults.standard.set($profilSurname.wrappedValue, forKey: "surnname")
}, label: {
Text("Update")
.frame(width:300 , height: 40)
.padding(10)
.font(Font.system(size: 30, weight: .medium, design: .serif))
.foregroundColor(.white)
.background(RoundedRectangle(cornerRadius: 45))
.foregroundColor(.init(red: 45 / 255, green: 0 / 255, blue: 112 / 255))
})
Getting stored values form Userdefaults
let surnName = UserDefaults.standard.object(forKey: "surnname") as? String ?? ""

Align Text with padding SwiftUI

I am creating a view that looks like this -
I am struggling to align the summary text with the text inside the image overlay.
I would like the leading edge of Research to align with the leading edge of My experience.
At the moment my view is rendering as
As you can see text view is too close to the leading edge.
I have tried adding .padding() but the view changes to
How can I properly inset the text so these 2 components line up?
import SwiftUI
struct ContentView: View {
var body: some View {
ZStack {
FeaturedContentCard()
.frame(minHeight: 100)
}.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct FeaturedContentCard: View {
var body: some View {
VStack {
ImageWithTextOverlayView(image: "featured_image", text: "My experience with EAP and Income Protection")
ContentCardSummary(text: "Research shows that our social enviroment significantly impacts our biology")
.padding(.all)
ContentCardMetaView(readTime: "10 min read", name: "Jessica Bell")
}
.padding(.bottom, 16)
.background(Color.white)
.feedItemContainer()
}
}
struct ImageWithTextOverlayView: View {
private(set) var image: String
private(set) var text: String
var body: some View {
Image(image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(minWidth: 0, maxWidth: .infinity)
.overlay(LinearGradient(gradient: Gradient(colors: [Color(#colorLiteral(red: 0, green: 0, blue: 0, alpha: 0.6536279966)), Color(#colorLiteral(red: 0, green: 0, blue: 0, alpha: 0))]), startPoint: .bottom, endPoint: .top))
.overlay(
Text(text)
.foregroundColor(Color.white)
.font(.title)
.padding(),
alignment: .bottomLeading
)
}
}
struct ContentCardSummary: View {
private(set) var text: String
var body: some View {
Text(text)
.frame(alignment: .leading)
.foregroundColor(Color(#colorLiteral(red: 0.2901960784, green: 0.2901960784, blue: 0.2901960784, alpha: 1)))
}
}
struct FeedItemContainer: ViewModifier {
func body(content: Content) -> some View {
content
.clipShape(RoundedRectangle(cornerRadius: 12, style: .continuous))
.customShadow()
}
}
struct BenefexShadow: ViewModifier {
func body(content: Content) -> some View {
content
.shadow(color: Color(.init(red: 0.18, green: 0.18, blue: 0.18, alpha: 0.16)).opacity(1), radius: 4, x: 0, y: 1)
.shadow(color: Color(.init(red: 0.18, green: 0.18, blue: 0.18, alpha: 0.1)).opacity(1), radius: 60, x: 0, y: 4)
.shadow(color: Color(.init(red: 0.18, green: 0.18, blue: 0.18, alpha: 0.16)).opacity(1), radius: 4, x: 0, y: 1)
}
}
extension View {
func customShadow() -> some View {
self.modifier(BenefexShadow())
}
func feedItemContainer() -> some View {
self.modifier(FeedItemContainer())
}
}
struct AvatarView: View {
var body: some View {
Image("profile_pic")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 40, height: 40)
.clipShape(Circle())
.overlay(
Circle()
.stroke(Color.white, lineWidth: 2)
)
.customShadow()
}
}
struct ContentCardMetaView: View {
private(set) var readTime: String
private(set) var name: String
var body: some View {
HStack(spacing: 8) {
AvatarView()
VStack(alignment: .leading) {
Text(readTime)
.font(.subheadline)
.foregroundColor(Color(#colorLiteral(red: 0.2901960784, green: 0.2901960784, blue: 0.2901960784, alpha: 1)))
Text(name)
.fontWeight(.medium)
.foregroundColor(Color(#colorLiteral(red: 0.2980392157, green: 0.1843137255, blue: 0.737254902, alpha: 1)))
}
Spacer()
Button(action: { }) {
Image(systemName: "ellipsis")
.font(.system(size: 24))
.foregroundColor(Color(#colorLiteral(red: 0.7803921569, green: 0.7803921569, blue: 0.7803921569, alpha: 1)))
.rotationEffect(.degrees(-90))
}
}
}
}
Here is fix. Tested with Xcode 11.4 / iOS 13.4
1) Remove padding at top layer, so
ImageWithTextOverlayView(image: "large_image", text: "My experience with EAP and Income Protection")
ContentCardSummary(text: "Research shows that our social enviroment significantly impacts our biology")
ContentCardMetaView(readTime: "10 min read", name: "Jessica Bell")
2) Correct alignment of summary, as
struct ContentCardSummary: View {
private(set) var text: String
var body: some View {
Text(text)
.frame(maxWidth: .infinity, alignment: .leading) // << full width
.padding() // << same padding as above text
.foregroundColor(Color(#colorLiteral(red: 0.2901960784, green: 0.2901960784, blue: 0.2901960784, alpha: 1)))
}
}

Resources