I don't know what to put in the view placeholder - swift

I keep getting an error to insert "proxy: /GeometryProxy/" even when "proxy" is a state variable. I have the code for the preview below. I don't know what to put in the placeholder and I am confused. I have included my full code to review. Please look below.
struct MathematicallyMainController_Previews: PreviewProvider {
static var previews: some View {
MathematicallyMainController(proxy: // what do i put here?)
}
}
My full code:
This is where the problem with the 'var' is happening.
struct MathematicallyMainController: View {
#StateObject var tabBarModel = TabBarViewModel()
#Environment(\.colorScheme) var colorScheme
#State var selectedIndex = 0
#State var isSelectedA = false
#State var isSelectedB = false
#State var isSelectedC = false
#State var isSelectedD = false
#State var isSelectedE = false
#State var proxy: GeometryProxy
var body: some View {
ZStack {
let bottomEdge = proxy.safeAreaInsets.bottom
switch selectedIndex {
case 0:
HomeViewController()
case 1:
BrowseView()
case 2:
RewardsView()
case 3:
EssentialsView()
case 4:
SchoolModeView()
default:
HomeViewController()
}
ZStack {
RoundedRectangle(cornerRadius: 15)
.fill(.regularMaterial)
.colorScheme(colorScheme == .dark ? .dark : .light)
HStack(alignment: .center) {
Button {
selectedIndex = 0
} label: {
if selectedIndex == 0 {
ZStack {
Circle()
.blur(radius: 20)
.foregroundColor(.blue)
.frame(width: 60)
.padding([.leading, .trailing], 5)
Image(systemName: "house.fill")
.font(.title)
.foregroundColor(colorScheme == .dark ? .black : .white)
.padding([.leading, .trailing], 5)
}
} else {
Image(systemName: "house.fill")
.font(.title)
.foregroundColor(colorScheme == .dark ? .white : .black)
}
}
Button {
selectedIndex = 1
} label: {
if selectedIndex == 1 {
ZStack {
Circle()
.blur(radius: 20)
.foregroundColor(.indigo)
.frame(width: 60)
.padding(.leading, 15)
Image(systemName: "rectangle.stack.fill")
.font(.title)
.foregroundColor(colorScheme == .dark ? .black : .white)
.padding(.leading, 15)
}
} else {
Image(systemName: "rectangle.stack.fill")
.font(.title)
.foregroundColor(colorScheme == .dark ? .white : .black)
.padding(.leading, 15)
}
}
Button {
selectedIndex = 2
} label: {
if selectedIndex == 2 {
ZStack {
Circle()
.blur(radius: 20)
.foregroundColor(.orange)
.frame(width: 60)
.padding([.trailing, .leading], 15)
Image(systemName: "circle.dotted")
.font(.title)
.foregroundColor(colorScheme == .dark ? .black : .white)
.padding([.trailing, .leading], 15)
}
} else {
Image(systemName: "circle.dotted")
.font(.title)
.foregroundColor(colorScheme == .dark ? .white : .black)
.padding(.trailing, 15)
.padding(.leading, 15)
}
}
Button {
selectedIndex = 3
} label: {
if selectedIndex == 3 {
ZStack {
Circle()
.blur(radius: 20)
.foregroundColor(.green)
.frame(width: 60)
.padding(.trailing, 15)
Image(systemName: "doc.text.image")
.font(.title)
.foregroundColor(colorScheme == .dark ? .black : .white)
.padding(.trailing, 15)
}
} else {
Image(systemName: "doc.text.image")
.font(.title)
.foregroundColor(colorScheme == .dark ? .white : .black)
.padding(.trailing, 15)
}
}
Button {
selectedIndex = 4
} label: {
if selectedIndex == 4 {
ZStack {
Circle()
.blur(radius: 20)
.foregroundColor(.purple)
.frame(width: 60)
.padding([.leading, .trailing], 5)
Image(systemName: "graduationcap.fill")
.font(.title)
.foregroundColor(colorScheme == .dark ? .black : .white)
.padding([.leading, .trailing], 5)
}
} else {
Image(systemName: "graduationcap.fill")
.font(.title)
.foregroundColor(colorScheme == .dark ? .white : .black)
}
}
}
.colorScheme(colorScheme == .dark ? .dark : .light)
.padding(.horizontal)
}
.frame(height: 60)
.shadow(color: .primary, radius: -10)
.shadow(color: .black, radius: 10)
.padding([.horizontal])
.padding(.bottom)
.frame(maxHeight: .infinity, alignment: .bottom)
.modifier(OffsetModifier())
.environmentObject(tabBarModel)
.offset(y: tabBarModel.tabState == .floating ? 0 : bottomEdge)
}
}
}
This is my ViewModifier I have included to create the scrolling animation.
struct OffsetModifier: ViewModifier {
#EnvironmentObject var model: TabBarViewModel
func body(content: Content) -> some View {
content
.overlay(
GeometryReader { proxy -> Color in
let minY = proxy.frame(in: .global).minY
DispatchQueue.main.async {
let durationOffset: CGFloat = 35
if minY < model.offset {
if model.offset < 0 && -minY > (model.lastStoredOffset + durationOffset) {
withAnimation(.easeOut.speed(1)) {
model.tabState = .floating
}
model.lastStoredOffset = -model.offset
}
}
if minY > model.offset && -minY < (model.lastStoredOffset + durationOffset) {
withAnimation(.easeOut.speed(1)) {
model.tabState = .expanded
}
model.lastStoredOffset = -model.offset
}
model.offset = minY
}
return Color.clear
}
,alignment: .top
)
}
}

The only time you ever use proxy is on this line:
let bottomEdge = proxy.safeAreaInsets.bottom
Therefore, there's no reason to pass in the entire GeometryProxy -- you can just pass in the bottom inset. Also, it definitely doesn't need to be a #State variable -- #State is used when the View needs to mutate its state over time -- this is just a parameter being passed in.
Change this line:
#State var proxy: GeometryProxy
to:
var bottomInset : CGFloat = 0
Because it has a default value, your preview can turn into this:
static var previews: some View {
MathematicallyMainController()
}
If you really wanted to pass a value (say, from the parent of the View), you would do something like this:
GeometryReader { proxy in
//other view code...
MathematicallyMainController(bottomInset: proxy.safeAreaInsets.bottom)
//other code...
}
There's also the option of moving the GeometryReader inside of MathematicallyMainController, but I'm assuming there's a reason you had it outside to begin with.
All of that being said, it looks like you have some unnecessary and unused code that you could clean up. For example, none of the isSelectedA-E variables ever get used. There's probably more here that can be refactored, but is outside of the scope of the present question.

Related

How to set max width of searchview inside toolbar [SwiftUI]

I am new to SwiftUI and I trying to set maxwidth of my searchbar inside of my toolbar but the .frame(maxWidth: .infinity) won't work on my case. How can I fix this?
You can see the problem by bellow attached image, Screenshot
// this is my toolbar
My ToolbarView
NavigationView {
VStack {
contentView
}
.padding(.top, 10)
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
if (hideTitleAndSearchButton) {
SearchBarView(
searchText: $viewModel.personViewModel.searchText,
hideTitleAndSearchButton: Binding(projectedValue: $hideTitleAndSearchButton),
viewModel: viewModel.personViewModel
)
.frame(maxWidth: .infinity)
.animationDisable()
}
else {
Text(title)
.font(.system(size: 32))
.bold()
}
}
ToolbarItem(placement: .navigationBarTrailing) {
if (!hideTitleAndSearchButton) {
if (viewModel.setSearchButtonVisibility) {
Image(systemName: "magnifyingglass")
.onTapGesture {
self.hideTitleAndSearchButton = true
}
.frame(width: 45, height: 45)
.foregroundColor(Color.white)
.background(Color.mPurple)
.clipShape(Circle())
.animationDisable()
}
}
}
}
}
.frame(maxWidth: .infinity)
// this is my searchview
My Searchview
var body: some View {
HStack {
Image("back_icon")
.resizable()
.renderingMode(.template)
.foregroundColor(.mPurple)
.onTapGesture {
self.isEditing = false
self.searchText = ""
self.hideTitleAndSearchButton = false
viewModel.isSearchMode = false
viewModel.isLoading = true
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
viewModel.personPopularList.removeAll()
viewModel.getPersonPopular()
}
}
.frame(width: 40, height: 40)
.animationDisable()
TextField("Search ...", text: $searchText)
.padding(7)
.padding(.horizontal, 20)
.background(Color(.systemGray6))
.cornerRadius(8)
.accentColor(.mPurple)
.frame(maxWidth: .infinity)
.onTapGesture {
self.isEditing = true
viewModel.isSearchMode = true
}.onChange(of: searchText) { searchItem in
if (!searchItem.isEmpty) {
viewModel.searchText = searchItem.lowercased()
let _ = print("searchItem true")
} else {
viewModel.isSearchMode = false
viewModel.personPopularList.removeAll()
viewModel.getPersonPopular()
let _ = print("searchItem false")
}
let _ = print("searchItemX: \(searchText)")
}
.animationDisable()
.padding(.trailing, 10)
}
}
thanks for anyone can help.
Add your SearchView in principal placement and don't need to set any width.
ToolbarItem(placement: hideTitleAndSearchButton ? .principal : .navigationBarLeading) {
if (hideTitleAndSearchButton) {
SearchBarView(
searchText: $viewModel.personViewModel.searchText,
hideTitleAndSearchButton: Binding(projectedValue: $hideTitleAndSearchButton),
viewModel: viewModel.personViewModel
)
.animationDisable()
}
else {
Text(title)
.font(.system(size: 32))
.bold()
}
}

SwiftUI - View is Wrong on iPad

I followed a tutorial to create a navigation menu, but I have a problem. On iPhone it is looks amazing, but on iPad I can't figure the problem.
It seems that I have a "back" button under the menu-button and If I press on it, it will show (kind-off) the page.
ScreenShoots will tell more.
Screens: https://imgur.com/a/i1Xv32t
Here is the code:
Main View
import SwiftUI
struct MainView: View {
#State var selectedTab = "Home"
#State var showMenu = false
#Environment(\.colorScheme) var colorScheme
var body: some View {
ZStack {
Color("myblue")
.ignoresSafeArea()
// Side Menu
ScrollView(getRect().height < 750 ? .vertical : .init(), showsIndicators: false, content: {
SideMenu(selectedTab: $selectedTab)
})
ZStack {
if colorScheme == .dark {
Color.black
.opacity(0.5)
.cornerRadius(showMenu ? 15 : 0)
.shadow(color: Color.black.opacity(0.07), radius: 5, x: -5, y: 0)
.offset(x: showMenu ? -25 : 0)
.padding(.vertical, 30)
Color.black
.opacity(0.4)
.cornerRadius(showMenu ? 15 : 0)
.shadow(color: Color.black.opacity(0.07), radius: 5, x: -5, y: 0)
.offset(x: showMenu ? -50 : 0)
.padding(.vertical, 60)
} else {
Color.white
.opacity(0.5)
.cornerRadius(showMenu ? 15 : 0)
.shadow(color: Color.black.opacity(0.07), radius: 5, x: -5, y: 0)
.offset(x: showMenu ? -25 : 0)
.padding(.vertical, 30)
Color.white
.opacity(0.4)
.cornerRadius(showMenu ? 15 : 0)
.shadow(color: Color.black.opacity(0.07), radius: 5, x: -5, y: 0)
.offset(x: showMenu ? -50 : 0)
.padding(.vertical, 60)
}
Home(selectedTab: $selectedTab)
.cornerRadius(showMenu ? 15 : 1)
}
// Scalling and Moving The View
.scaleEffect(showMenu ? 0.84 : 1)
.offset(x: showMenu ? getRect().width - 120 : 0)
.ignoresSafeArea()
.overlay(
// Menu Button
Button(action: {
withAnimation(.spring()) {
showMenu.toggle()
}}, label: {
VStack (spacing: 5) {
Capsule()
.fill(showMenu ? Color.white : Color.primary)
.frame(width: 30, height: 3)
.rotationEffect(.init(degrees: showMenu ? -50 : 0))
.offset(x: showMenu ? 2 : 0, y: showMenu ? 9 : 0)
VStack (spacing: 5) {
Capsule()
.fill(showMenu ? Color.white : Color.primary)
.frame(width: 30, height: 3)
Capsule()
.fill(showMenu ? Color.white : Color.primary)
.frame(width: 30, height: 3)
.offset(y: showMenu ? -8 : 0)
}
.rotationEffect(.init(degrees: showMenu ? 50 : 0))
}
})
.padding()
,alignment: .topLeading
)
}
}
}
struct MainView_Previews: PreviewProvider {
static var previews: some View {
MainView()
}
}
extension View {
func getRect()->CGRect {
return UIScreen.main.bounds
}
}
Home
import SwiftUI
struct Home: View {
#Binding var selectedTab: String
init(selectedTab: Binding<String>) {
self._selectedTab = selectedTab
UITabBar.appearance().isHidden = true
}
var body: some View {
// Tab View with Tabs
TabView(selection: $selectedTab) {
// Views
HomePage()
.tag("Home")
History()
.tag("History")
Notifications()
.tag("Notifications")
Settings()
.tag("Settings")
Help()
.tag("Help")
}
}
}
struct Home_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct HomePage: View {
var body: some View {
NavigationView {
Text("Home")
.font(.largeTitle)
.fontWeight(.heavy)
.foregroundColor(.primary)
.navigationTitle("Home")
}.navigationBarBackButtonHidden(true)
}
}
struct History: View {
var body: some View {
NavigationView {
Text("History")
.font(.largeTitle)
.fontWeight(.heavy)
.foregroundColor(.primary)
.navigationTitle("History")
}
}
}
struct Notifications: View {
var body: some View {
NavigationView {
Text("Notifications")
.font(.largeTitle)
.fontWeight(.heavy)
.foregroundColor(.primary)
.navigationTitle("Notifications")
}
}
}
struct Settings: View {
var body: some View {
NavigationView {
Text("Settings")
.font(.largeTitle)
.fontWeight(.heavy)
.foregroundColor(.primary)
.navigationTitle("Settings")
}
}
}
struct Help: View {
var body: some View {
NavigationView {
Text("Help")
.font(.largeTitle)
.fontWeight(.heavy)
.foregroundColor(.primary)
.navigationTitle("Help")
}
}
}
Found de issue!
Had to remove NavigationView { } from every struct XYZ: View { }.

I'd like to use the navigation link.Newbie Wang is in the process of hair loss

I want to use Navigationlink. I've been a novice for 2 weeks since I started.I am currently learning SwiftUi.
I created "OnboredView" after watching YouTube, but I don't know how to connect "OnboredView" to "CountentView".
NavigationView(){
NavigationLink(destination: OnboardView())
I learned how to make it like this through YouTube, but I don't know what to do now. I put it here and there, but the red errors bother me.
Tell me how to connect "NavigationLink" by pressing the button on "CountentView".
I'd like to click "Chevron.Light" to move on to "OnboredView."And if possible, please let me know how I can get rid of the "onboard screen" on the second run?
I am not good at English.I'm sorry. I'm experiencing hair loss again.
import SwiftUI
struct ContentView: View {
#State private var animate: Bool = false
var body: some View {
ZStack{
ZStack{
Image("rogo1")
.resizable()
.frame(width: 75, height: 75)
.offset(y: animate ? -100 : 0)
}
ZStack{
Image("rogo2")
.resizable()
.frame(width: 75, height: 75)
.offset(y: animate ? -100 : 0)
}
VStack {
HStack {
Spacer()
Image("images (1)")
.resizable()
.frame(width: 300, height: 300)
.offset(x: animate ? 300 : 150, y: animate ? -300 : -150)
}
Spacer()
HStack {
Image("images (1)")
.resizable()
.frame(width: 400, height: 400)
.offset(x: animate ? -500 : -150, y: animate ? 500 : 150)
Spacer()
}
}
ZStack(alignment: .bottom){
GeometryReader { g in
VStack (alignment: .leading, spacing: 20){
Text("안녕하세요!")
.font(.title)
.fontWeight(.semibold)
.padding(.top, 20)
//인삿말과 회원가입
Text("기분 좋은 매일습관을 만들기 위한 앱 ( ) 입니다! 시간표와 더불어 루틴을 함께 할수
있도록 설계 되었습니다.저희 ( )와 함께 계획해봐요!")
.fontWeight(.medium)
.multilineTextAlignment(.center)//중앙으로 결집
.padding(5)
ZStack {
Button(action: {},label: {
Image(systemName: "chevron.right")
.font(.system(size:20, weight: .semibold))
.frame(width: 60, height: 60)
.foregroundColor(.black)
.background(Color.white)
.clipShape(Circle())
.overlay(
ZStack {
Circle()
.stroke(Color.black.opacity(0.04),lineWidth: 4)
Circle()
.trim(from: 0, to: 0.03)
.stroke(Color.white,lineWidth: 4)
.rotationEffect(.init(degrees: -40))
})
})
.padding(-10)
}
Spacer()
}
.frame(maxWidth: .infinity)
.padding(.horizontal, 30)
.background(Color.green)
.clipShape(CustomShape(leftCorner: .topLeft, rightCorner: .topRight,
radii: 20))
.offset(y: animate ? g.size.height : UIScreen.main.bounds.height)
}
}.frame(height: 275)
//여기까지 짤라도 됨 온보드
}
.frame(maxWidth: .infinity)
.edgesIgnoringSafeArea(.all)
.onAppear(perform: {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
withAnimation(Animation.easeOut(duration: 0.45)){
animate.toggle()
}
}
})
}
{
struct CustomShape: Shape {
var leftCorner: UIRectCorner
var rightCorner: UIRectCorner
var radii: CGFloat
func path(in rect: CGRect) -> Path {
let path = UIBezierPath(roundedRect: rect, byRoundingCorners:
[leftCorner,rightCorner], cornerRadii: CGSize(width: radii, height: radii))
return Path(path.cgPath)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
Group {
}
}
}
}
import SwiftUI
struct OnboardView: View {
#AppStorage("currentPage") var currentPage = 1
var body: some View {
if currentPage > totalPages {
Home()
}else{
WalkthroughScreen()
}
}
}
struct OnboardView_Previews: PreviewProvider {
static var previews: some View {
OnboardView()
}
}
struct Home: View {
var body: some View{
Text("welcome To Home!!!")
.font(.title)
.fontWeight(.heavy)
}
}
//..Walkthrough Screen..
struct WalkthroughScreen: View {
#AppStorage("currentPage") var currentPage = 1
var body: some View {
//For Slide Animation
ZStack{
//Changing Between Views..
if currentPage == 1 {
ScreenView(image: "image1", title: "Step1", detail: "", bgColor:
Color(.white))
//transition(.scale)영상에서는 넣었으나 오류가나서 사용하지 못함
}
if currentPage == 2 {
ScreenView(image: "image2", title: "Step2", detail: "", bgColor:
Color(.white))
}
if currentPage == 3 {
ScreenView(image: "image3", title: "Step3", detail: "아니 ㅡㅡ 이런 방법이 유레카",
bgColor: Color(.white))
}
}
.overlay(
Button(action: {
//changing views
withAnimation(.easeInOut){
if currentPage < totalPages {
currentPage += 1
}else{
currentPage = 1
//For app testing ONly
}
}
}, label: {
Image(systemName: "chevron.right")
.font(.system(size: 20, weight: .semibold))
.foregroundColor(.black)
.frame(width: 60, height: 60)
.clipShape(Circle())
//strclulat Slider
.overlay(
ZStack{
Circle()
.stroke(Color.black.opacity(0.04),lineWidth: 4
Circle()
.trim(from: 0, to: CGFloat(currentPage) /
CGFloat(totalPages))
.stroke(Color.green,lineWidth: 4)
.rotationEffect(.init(degrees: -99))
}
.padding(-15)
)
})
.padding(.bottom,20)
,alignment: .bottom
)
}
}
struct ScreenView: View {
var image: String
var title: String
var detail: String
var bgColor: Color
#AppStorage("currentPage") var currentPage = 1
var body: some View {
VStack(spacing:20){
HStack {
//Showing it only for first page..
if currentPage == 1{
Text("Hello Members!")
.font(.title)
.fontWeight(.semibold)
//Letter Spacing
.kerning(1.4)
}else{
//Back Butten..
Button(action: {
withAnimation(.easeInOut){
currentPage -= 1
}
}, label: {
Image(systemName: "chevron.left")
.foregroundColor(.white)
.padding(.vertical,10)
.padding(.horizontal)
.background(Color.black.opacity(0.4))
.cornerRadius(10)
})
}
Spacer()
Button(action: {
withAnimation(.easeInOut){
currentPage = 4
}
}, label: {
Text("Skip")//글자입력
.fontWeight(.semibold)//글자 폰트변경
.kerning(1.2)//글자간 간격 조정
})
}
.foregroundColor(.black)//그라운드 컬러 변경
.padding()
Spacer(minLength: 0)//수평,수직 줄바꿈
Image(image)//이미지 삽입
.resizable()//크기 확대
.aspectRatio(contentMode: .fit)//이미지 크기
Text(title)
.font(.title)//폰트 크기변경
.fontWeight(.bold)//폰트 두께 변경
.foregroundColor(.black)//색깔 변경
.padding(.top)
//Change with your Own Thing..
Text(detail)
.fontWeight(.semibold)
.kerning(1.3)//자간조정
.multilineTextAlignment(.center)//텍스트를 중앙으로 결집
Spacer(minLength: 220)//minimun Spacing When phone is reducing수직위치 조정
}
.background(bgColor.cornerRadius(10).ignoresSafeArea())
}
}
var totalPages = 3

How to change view with Navigationlink with two conditions in SwiftUI?

I have 3 buttons in my view. I want to change view with navigationlink when 2 buttons are active. When I tap to tap1 and tap3 I want to go to ViewOne(), when I tap to tap2 and tap3 I want to ViewTwo() How can I do that ?
#State var tap1 : Bool = false
#State var tap2 : Bool = false
#State var tap3 : Bool = false
NavigationLink(destination: ViewOne(), isActive: $tap1, label: {
VStack{
Image("smile")
.resizable()
.renderingMode(.original)
.aspectRatio(contentMode: .fit)
.frame(width: 150, height: 90)
Text("Fine")
.font(.system(size: 50, weight: .thin))
.padding(.bottom, 30)
}
NavigationLink(destination: ViewTwo(), isActive: $tap2) {
VStack{
Image("sad")
.resizable()
.renderingMode(.original)
.aspectRatio(contentMode: .fit)
.frame(width: 150, height: 90)
Text("Bad")
.font(.system(size: 50, weight: .thin))
.padding(.bottom, 30)
}
NavigationLink(destination: ?(), isActive: $tap3) {
Text("Continue")
You can try the following:
struct ContentView: View {
#State var tap1: Bool = false
#State var tap2: Bool = false
#State var isLinkActive: Bool = false
var body: some View {
NavigationView {
VStack {
button1
button2
button3
}
}
}
var button1: some View {
Button(action: {
self.tap1.toggle()
}) {
VStack {
Image("smile")
.resizable()
.renderingMode(.original)
.aspectRatio(contentMode: .fit)
.frame(width: 150, height: 90)
Text("Fine")
.font(.system(size: 50, weight: .thin))
.padding(.bottom, 30)
}
}
.background(tap1 ? Color.green : .clear)
}
var button2: some View {
Button(action: {
self.tap2.toggle()
}) {
VStack {
Image("sad")
.resizable()
.renderingMode(.original)
.aspectRatio(contentMode: .fit)
.frame(width: 150, height: 90)
Text("Bad")
.font(.system(size: 50, weight: .thin))
.padding(.bottom, 30)
}
}
.background(tap2 ? Color.red : .clear)
}
var button3: some View {
Button(action: {
// make sure you set the link only when ready
// what should happen if tap1 and tap2 are true?
self.isLinkActive.toggle()
}) {
Text("Continue")
}
.background(
NavigationLink(destination: destinationView, isActive: $isLinkActive) {
EmptyView()
}
.hidden()
)
}
#ViewBuilder
var destinationView: some View {
if tap1 {
Text("ViewOne")
} else if tap2 {
Text("ViewTwo")
}
}
}

Ternary operator issue SwiftUI

I'm using a ternary operator in my swiftui view to change the foreground color of an item.
When using this as code everything compiles normal:
Circle()
.frame(width: 10, height: 10)
.foregroundColor(item.amount < 10 ? Color.green : Color.red)
When using this, my project does not build, CPU of my Mac starts spiking, fans kicking in etc. Anyone an idea what's wrong ?
Circle()
.frame(width: 10, height: 10)
.foregroundColor(item.amount < 10 ? Color.green : (item.amount < 100 ? Color.orange : Color.red))
Complete code:
struct ContentView: View {
#ObservedObject var expenses = Expenses()
#State private var showAddExpense = false
var body: some View {
NavigationView {
List {
ForEach (expenses.items) { item in
HStack {
VStack(alignment: .leading) {
Text(item.name)
.font(.headline)
Text(item.type)
}
Spacer()
Text("€\(item.amount)")
Circle()
.frame(width: 10, height: 10)
.foregroundColor(item.amount < 10 ? Color.green : (item.amount < 100 ? Color.orange : Color.red))
}
}
.onDelete(perform: removeItem)
}
.navigationBarTitle("iExpense")
.navigationBarItems(leading: EditButton(), trailing:
Button(action: {
self.showAddExpense = true
}
) {
Image(systemName: "plus")
})
}
.sheet(isPresented: $showAddExpense) {
AddView(expenses: self.expenses)
}
}
func removeItem(at index: IndexSet) {
expenses.items.remove(atOffsets: index)
}
}
Error showing on the sheet modifier, but this one is correct.
Break body construction for smaller components, like below
ForEach (expenses.items) { item in
self.listRow(for: item) // << extract !!
}
.onDelete(perform: removeItem)
,say, to private row generator function
private func listRow(for item: Item) -> some View { // << your item type here
HStack {
VStack(alignment: .leading) {
Text(item.name)
.font(.headline)
Text(item.type)
}
Spacer()
Text("€\(item.amount)")
Circle()
.frame(width: 10, height: 10)
.foregroundColor(item.amount < 10 ? Color.green : (item.amount < 100 ? Color.orange : Color.red))
}
}