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 = 38
let title: String
let size: CGSize
let backgroundColorName: String
let action: ()->Void
var 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) //圆角
})
}
}
/// 封装的每一行 ,使用foreach
struct CalculatorButtonRow: View {
let row: [CalculatorButtonItem] //每一行里面的元素button
var body: some View {
HStack{ //水平布局
ForEach(row, id: \.self) { item in //使用foreach水平布局button
CalculatorButton(
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 in
CalculatorButtonRow(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 编程