xxxxxxxxxximport SwiftUI
@mainstruct How_MuchApp: App { var body: some Scene { WindowGroup { ContentView() .tint(.purple) } }}xxxxxxxxxximport SwiftUI
struct ContentView: View { @State private var tipPct = 0 @State private var numPeople = 1 @State private var total = "0" @State private var calculate = false var canAddDecimal: Bool {// let periods = total.filter({$0 == "."})// if periods.count == 0 {// return true// } else {// return false// }// return total.filter({$0 == "."}).count == 0 total.filter({$0 == "."}).count == 0 } var canAddDigit: Bool { guard let decIndex = total.firstIndex(of: ".") else { return true } let index = total.distance(from: total.startIndex, to: decIndex) return (total.count - index - 1) < 2 } var body: some View { NavigationStack { VStack { Text(total) .font(.system(size: 70)) .frame(width: 260, alignment: .trailing) .padding(.vertical,1) .lineLimit(1) .minimumScaleFactor(0.5) HStack { ForEach(7...9, id: \.self) { number in numberButton(number: "\(number)") } } HStack { ForEach(4...6, id: \.self) { number in numberButton(number: "\(number)") } } HStack { ForEach(1...3, id: \.self) { number in numberButton(number: "\(number)") } } HStack { numberButton(number: "0") numberButton(number: ".") Button { if total.count == 1 { total = "0" } else { total.removeLast() } } label: { Image(systemName: "delete.backward.fill") .font(.largeTitle) .bold() .frame(width: 80, height: 80) .background(.gray) .foregroundColor(.white) .clipShape(Circle()) } } HStack { Text("Tip") Picker(selection: $tipPct, label: Text("Tip")) { ForEach(0...100,id: \.self) { tip in Text("\(tip)%") } } .buttonStyle(.bordered) } HStack { Text("Number of people") Picker(selection: $numPeople, label: Text("Number of People")) { ForEach(1...20,id: \.self) { numPeople in Text("\(numPeople)").tag(numPeople) } } .buttonStyle(.bordered) } HStack { Button("Calculate") { calculate = true } .sheet(isPresented: $calculate) { TotalsView(total: Double(total) ?? 0, tipPct: tipPct, numPeople: numPeople) .presentationDetents([.medium]) } Button("Clear") { total = "0" } } .disabled(Double(total) == 0) .buttonStyle(.borderedProminent) Spacer() } .navigationTitle("Portion Calculator") } } func numberButton(number: String) -> some View { Button { addDigit(number) } label: { Text(number) .font(.largeTitle) .bold() .frame(width: 80, height: 80) .background(.purple) .foregroundColor(.white) .clipShape(Circle()) } } func addDigit(_ number: String) { if canAddDigit { if number == "." { if canAddDecimal { total += number } } else { total = total == "0" ? number : total + number } } }}
struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() .tint(.purple) }}xxxxxxxxxx//// Created for How Much// by Stewart Lynch on 2023-02-07// Using Swift 5.0// Running on macOS 13.2// // Folllow me on Mastodon: @StewartLynch@iosdev.space// Or, Twitter, if it still exits: https://twitter.com/StewartLynch// Subscribe on YouTube: https://youTube.com/@StewartLynch// Buy me a ko-fi: https://ko-fi.com/StewartLynch
import SwiftUI
struct TotalsView: View { let total: Double let tipPct: Int let numPeople: Int var tipAmount: Double { total * Double(tipPct) / 100 } var totalAmount: Double { total + tipAmount } var portion: Double { totalAmount / Double(numPeople) } let identifier = Locale.current.currency?.identifier ?? "" var body: some View { NavigationStack { VStack { Grid(horizontalSpacing: 20) { GridRow { Text("Original Bill") .gridColumnAlignment(.leading) Text("\(total, format: .currency(code: identifier))") .gridColumnAlignment(.trailing) } GridRow { Text("Tip") Text("\(tipAmount, format: .currency(code: identifier))") } GridRow { Text("Total") Text("\(totalAmount, format: .currency(code: identifier))") } GridRow { Text("Portion") Text("\(portion, format: .currency(code: identifier))") } } .font(.title) Image("myportion") .resizable() .scaledToFit() .frame(width: 150) Spacer() } .navigationTitle("Amount Owing") .navigationBarTitleDisplayMode(.inline) } }}
struct TotalsView_Previews: PreviewProvider { static var previews: some View { TotalsView(total: 135.20, tipPct: 18, numPeople: 3) }}