
ContentView.swift
import SwiftUI///按钮宽度let size_width = 65///主内容视图struct ContentView: View {var body: some View {//垂直布局VStack(spacing: 12, content: {Spacer() //为了填充上面的留白Text("0") //输入显示的区域.font(.system(size: 76)).frame(minWidth: 0,maxWidth: .infinity, //最大alignment: .trailing //靠右)CalculatorButtonPad() //计算器上面的按键.padding(.bottom) //底部留白为0})}}///效果显示调用的地方struct ContentView_Previews: PreviewProvider {static var previews: some View {ContentView()}}///每个button的封装struct CalculatorButton : View {let fontSize: CGFloat = 38let title: Stringlet size: CGSizelet backgroundColorName: Stringlet action: ()->Voidvar body: some View {Button(action: action, label: {Text(title).font(.system(size: fontSize)) //字体.foregroundColor(.blue) //字色.frame(width: size.width, height: size.height) //size.background(Color(backgroundColorName)) //背景色.cornerRadius(size.width/2) //圆角})}}/// 封装的每一行 ,使用foreachstruct CalculatorButtonRow: View {let row: [CalculatorButtonItem] //每一行里面的元素buttonvar body: some View {HStack{ //水平布局ForEach(row, id: \.self) { item in //使用foreach水平布局buttonCalculatorButton(title: item.title,size: item.size,backgroundColorName: item.backgroundColorName) {print("button : \(item.title)")}}}}}/// 封装计算器上的所有按键struct CalculatorButtonPad: View {/// pad里面是每一行的数据,具体意思看下item类let pad: [[CalculatorButtonItem]] = [[.command(.clear), .command(.flip), .command(.percent), .op(.divide)],[.digit(7), .digit(8), .digit(9), .op(.multipy)],[.digit(4), .digit(5), .digit(6), .op(.minus)],[.digit(1), .digit(2), .digit(3), .op(.plus)],[.digit(0), .dot, .op(.equal)],]var body: some View {//垂直布局类VStack(spacing: 8, content: {//使用foreach添加每一行ForEach(pad, id: \.self) { row inCalculatorButtonRow(row: row)//每一行的数据}})}}
CalculatorButtonItem.swift
import Foundation
import SwiftUI
/// 计算机按钮上显示的布局
enum CalculatorButtonItem {
/// 加减乘除等计算符号
enum Op: String {
case plus = "+"
case minus = "-"
case divide = "÷"
case multipy = "x"
case equal = "="
}
/// 清空、符号反转、取余
enum Command: String {
case clear = "AC"
case flip = "+/-"
case percent = "%"
}
case digit(Int) ///0 - 9 的数据
case dot ///小数点
case op(Op) ///计算符号
case command(Command) //清空、反转、取余
}
///外观添加 内容
extension CalculatorButtonItem: Hashable {
//显示的内容(0-9 . + - x % 等等,根据不同的case显示不同的内容)
var title: String {
switch self {
case .digit(let value): return String(value)
case .dot: return "."
case .op(let op): return op.rawValue
case .command(let command): return command.rawValue
}
}
//每个按钮的大小
var size: CGSize {
if case .digit(let value) = self, value == 0 {
return CGSize(width: size_width * 2, height: size_width)
}
return CGSize(width: size_width, height: size_width)
}
//背景色
///背景色取值于 Assets.xcassets 见下图.
var backgroundColorName: String {
switch self {
case .digit, .dot: return "digitBackground"
case .op: return "operatorBackground"
case .command: return "commandBackground"
}
}
}
效果:

代码学习于:
猫神 swifter swiftui与combine 编程
