Decide to copy the interface and functionality from ios calculator app and got up to following stage.
I`m trying to use lazyVgrid for buttons I can make exact same interface but without lazyVgrid...if you compile the code and run youll see that "0" is not in right shape. I tried roundedrectangle playing with cornerradius and frame width but each time I couldnt make it work with lazyVgrid.
I watched some videos on youtube who implemented calculator app nobody used lazygrids. Also functionality was overly complicated I tried to keep it simple.
Didnt finish functionality for percent,decimal and negative/positive sign. Thats why all calculations are done with Ints.
And other issue I`m trying to solve is the actual textfield that I used I want to keep it up to 9 chars as native calculator app is doing in portrait mode. I can fit some digits up to 9 chars but some cant fit I need a way to readjust the textfields frame or ???
3 files myButtons.swift for just array of buttons, ButtonView.swift for making views in foreach for each button, and contentView.
//
// myButtons.swift
// Calculator
//
//
import Foundation
let myButtons = [
"AC","+/-","%","÷",
"7","8","9","×",
"4","5","6","−",
"1","2","3","+",
"0",".","="
]
//
// ButtonsView.swift
// Calculator
//
//
import SwiftUI
struct ButtonsView: View {
var name:String
var bgColor:Color{
switch name {
case "1","2","3","4","5","6","7","8","9","0",".":
return Color(.systemGray2)
case "AC","+/-","%":
return Color(.systemGray4)
default:
return .orange
}
}
var foregroundColor:Color{
switch name {
case "AC","+/-","%":
return .black
default:
return .white
}
}
var body: some View {
RoundedRectangle(cornerRadius: 50)
.fill(bgColor)
.frame(width: 80, height: 80)
.overlay(
Text(name)
.font(.largeTitle)
.foregroundColor(foregroundColor)
)
}
}
struct ButtonsView_Previews: PreviewProvider {
static var previews: some View {
ButtonsView(name: "0")
}
}
import SwiftUI
struct ContentView: View {
@State private var displayNumber = ""
@State private var operand1 = 0
@State private var operand2 = 0
@State private var calculation = ""
@State private var secondOperation = false //redundant workaround to start load operand2
let myGridItem = [GridItem(.flexible(minimum: 30, maximum: 100)),GridItem(.flexible(minimum: 30, maximum: 100)),GridItem(.flexible(minimum: 30, maximum: 100)),GridItem(.flexible(minimum: 30, maximum: 100))]
var body: some View {
ZStack {
Color.black.edgesIgnoringSafeArea(.all)
VStack{
HStack{
TextField("", text: $displayNumber)
.font(.system(size: 70))
.multilineTextAlignment(.trailing)
.foregroundColor(.white)
.frame(minWidth:0,maxWidth: .infinity,maxHeight: 150)
.padding(.horizontal,5)
}
VStack{
LazyVGrid(columns: myGridItem, content: {
ForEach(myButtons,id:\.self){buttons in
ButtonsView(name: buttons)
.onTapGesture {
checkOperation(input: buttons)
}
}
})
}.padding()
}
}
}
func checkOperation(input: String){
guard input != "AC" else {
restart()
return
}
guard input != "=" else{
if calculation.isEmpty{
return
}
else{
switch calculation {
case "+":
displayNumber = String(operand1 + operand2)
reset()
case "-":
displayNumber = String(operand1 - operand2)
reset()
case "*":
displayNumber = String(operand1 * operand2)
reset()
case "÷":
displayNumber = String(operand1 / operand2)
reset()
default:
print("hi there")
}
}
return
}
if Int(input) != nil {
sendToDisplay(input)
return
}
if calculation.isEmpty{ //workaround to clear the display and start loading operand2
calculation = input
secondOperation = true
}
else{
calculation = input
}
}
func restart(){
operand2 = 0
operand1 = 0
calculation = ""
displayNumber = ""
}
func reset(){
operand1 = 0
operand2 = 0
calculation = ""
}
func sendToDisplay(_ number:String){
guard displayNumber.count <= 9 else {
return
}
if secondOperation {
displayNumber = ""
secondOperation = !secondOperation
}
if calculation.isEmpty{
displayNumber += number
operand1 = Int(displayNumber)!
}
else{
displayNumber += number
operand2 = Int(displayNumber)!
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}