UserDefaults Text / SwiftUI - ios

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 ?? ""

Related

How to pass a Buttonbar to Views

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))
}
}
}
}

Confusion with passing data to another view. SwiftUI

I'm building this project, and I have two views: MenuView and CreateBoardView.
What I want to achieve is to be able to create a new board on the menu screen, and so that the data I'd enter (board name and description) would be shown in the new created box. But I'm really confused about how to make it.
Here's the code for my MenuView:
import Foundation
import SwiftUI
struct MenuView: View {
#EnvironmentObject var AboutBoard: BoardModel
var body: some View {
ZStack {
VStack {
HStack(spacing: 80) {
VStack(alignment: .leading, spacing: 10) {
Text("Hey,")
.font(Font.custom("Montserrat", size: 25))
Text("username")
.font(Font.custom("Montserrat-Bold", size: 30))
}
Image("Profile")
.resizable()
.scaledToFit()
.frame(width: 100, height: 100, alignment: .trailing)
}
.padding(.top, 30)
HStack(alignment: .top, spacing: 30) {
VStack(alignment: .leading) {
Text("New board")
.font(Font.custom("Montserrat-Bold", size: 25))
.foregroundColor(.white)
Text("Create with your friends")
.font(Font.custom("Montserrat", size: 18))
.foregroundColor(.white)
.padding(.bottom, 10)
NavigationLink(destination: CreateBoardView()) {
Text("Create board")
}.padding(15)
.frame(width: 180, height: 50, alignment:.center)
.background(LinearGradient(gradient: Gradient(colors: [(Color.init(red: 0.58, green: 0.12, blue: 0.68)), (Color.init(red: 0.58, green: 0.12, blue: 0.68))]), startPoint: .topLeading, endPoint: .bottomTrailing), in: RoundedRectangle(cornerRadius: 20))
.foregroundColor(.white)
.scaledToFill()
.font(Font.custom("Montserrat-Bold", size: 20))
.shadow(color: Color.init(red: 0.28, green: 0.00, blue: 0.34, opacity: 0.2), radius: 5, x: 0, y: 7)
.navigationBarBackButtonHidden(true)
.navigationBarTitleDisplayMode(.inline)
}
Image("Forum")
.resizable()
.scaledToFit()
.frame(width: 50, height: 50)
}
.frame(width: 350, height: 180, alignment: .center)
.background(LinearGradient(gradient: Gradient(colors: [(Color.init(red: 0.88, green: 0.33, blue: 1.00)), (Color.init(red: 0.69, green: 0.05, blue: 1.00))]), startPoint: .topLeading, endPoint: .bottomTrailing), in: RoundedRectangle(cornerRadius: 30))
HStack(spacing: 150) {
Text("Your boards")
.font(Font.custom("Montserrat-Bold", size: 20))
Text("See all")
.font(Font.custom("Montserrat", size: 15))
}.padding(.top, 20)
HStack(spacing: 30) {
ForEach(0..<10) {_ in
Text(AboutBoard.BoardName)
.font(Font.custom("Montserrat", size: 20))
Text(AboutBoard.BoardDescription)
.font(Font.custom("Montserrat", size: 20))
}
.frame(width: 250, height: 210)
.background(
Image("Board-Holder")
.resizable()
.scaledToFit()
.frame(width: 250, height: 210)
)
}
Spacer()
}
}
.environmentObject(BoardModel())
}
}
struct MenuPagePreview: PreviewProvider {
static var previews: some View {
MenuView()
}
}
And my CreateBoardView:
import Foundation
import SwiftUI
struct CreateBoardView: View {
#StateObject var BoardInfo = BoardModel()
#State private var SetDeadline = false
#State private var ShowMenu = false
var body: some View {
ZStack {
VStack {
Text("Create a new board")
.font(Font.custom("Montserrat-Medium", size: 30))
.padding(.bottom, 50)
.padding(.top, 50)
Text("Enter your board's name")
.font(Font.custom("Montserrat", size: 20))
.padding(.bottom, 30)
TextField("Board name", text: $BoardInfo.BoardName)
.padding(15)
.frame(width: 350, height: 60, alignment:.center)
.background(RoundedRectangle(cornerRadius: 20).fill(.white))
.scaledToFill()
.font(Font.custom("Montserrat", size: 20))
.shadow(color: Color.init(red: 0.28, green: 0.00, blue: 0.34, opacity: 0.2), radius: 15, x: 0, y: 7)
.padding(.bottom, 25)
.disableAutocorrection(true)
Text("Add board description")
.font(Font.custom("Montserrat", size: 20))
.padding(.bottom, 30)
TextField("Board description", text: $BoardInfo.BoardDescription)
.padding(15)
.frame(width: 350, height: 60, alignment:.center)
.background(RoundedRectangle(cornerRadius: 20).fill(.white))
.scaledToFill()
.font(Font.custom("Montserrat", size: 20))
.shadow(color: Color.init(red: 0.28, green: 0.00, blue: 0.34, opacity: 0.2), radius: 15, x: 0, y: 7)
.padding(.bottom, 25)
.disableAutocorrection(true)
NavigationLink(destination: MenuView()) {
Text("Create board")
}
.padding(15)
.frame(width: 350, height: 60, alignment:.center)
.background(LinearGradient(gradient: Gradient(colors: [(Color.init(red: 0.72, green: 0.26, blue: 0.67)), (Color.init(red: 0.47, green: 0.16, blue: 0.74))]), startPoint: .topLeading, endPoint: .bottomTrailing), in: RoundedRectangle(cornerRadius: 20))
.foregroundColor(.white)
.scaledToFill()
.font(Font.custom("Montserrat-Bold", size: 20))
.shadow(color: Color.init(red: 0.28, green: 0.00, blue: 0.34, opacity: 0.2), radius: 15, x: 0, y: 7)
.padding(.bottom, 25)
.sheet(isPresented: $ShowMenu){
MenuView()
}
}
}
}
}
struct CreateBoardPreview: PreviewProvider {
static var previews: some View {
CreateBoardView()
}
}
I also have this BoardModel but I don't know if I'm even doing it right.
import Foundation
import SwiftUI
class BoardModel: ObservableObject {
static let shared = BoardModel()
#Published var BoardName: String = ""
#Published var BoardDescription: String = ""
}
So how to make it such way so that the CreateBoardView would take the input and then have it stored and shown in the menu?
Thanks.

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.

Creating Alerts with SwiftUI

I want to create a warning but I couldn't do it according to this button. Can you create an alert based on this button?
Button(action: {
self.alertVisible = true
}, label: {
Text("Güncelle")
.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))
})
struct ContentView: View {
#State var alertVisible = false
var body: some View {
VStack {
Button(action: {
self.alertVisible = true
}, label: {
Text("Güncelle")
.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))
})
}
.alert(isPresented: $alertVisible) {
Alert(title: Text("Title"), message: Text("Message"), dismissButton: .default(Text("Got it!")))
}
}
}

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