VCG211224314368.jpg

ContentView.swift

  1. import SwiftUI
  2. ///按钮宽度
  3. let size_width = 65
  4. ///主内容视图
  5. struct ContentView: View {
  6. var body: some View {
  7. //垂直布局
  8. VStack(spacing: 12, content: {
  9. Spacer() //为了填充上面的留白
  10. Text("0") //输入显示的区域
  11. .font(.system(size: 76))
  12. .frame(
  13. minWidth: 0,
  14. maxWidth: .infinity, //最大
  15. alignment: .trailing //靠右
  16. )
  17. CalculatorButtonPad() //计算器上面的按键
  18. .padding(.bottom) //底部留白为0
  19. })
  20. }
  21. }
  22. ///效果显示调用的地方
  23. struct ContentView_Previews: PreviewProvider {
  24. static var previews: some View {
  25. ContentView()
  26. }
  27. }
  28. ///每个button的封装
  29. struct CalculatorButton : View {
  30. let fontSize: CGFloat = 38
  31. let title: String
  32. let size: CGSize
  33. let backgroundColorName: String
  34. let action: ()->Void
  35. var body: some View {
  36. Button(action: action, label: {
  37. Text(title)
  38. .font(.system(size: fontSize)) //字体
  39. .foregroundColor(.blue) //字色
  40. .frame(width: size.width, height: size.height) //size
  41. .background(Color(backgroundColorName)) //背景色
  42. .cornerRadius(size.width/2) //圆角
  43. })
  44. }
  45. }
  46. /// 封装的每一行 ,使用foreach
  47. struct CalculatorButtonRow: View {
  48. let row: [CalculatorButtonItem] //每一行里面的元素button
  49. var body: some View {
  50. HStack{ //水平布局
  51. ForEach(row, id: \.self) { item in //使用foreach水平布局button
  52. CalculatorButton(
  53. title: item.title,
  54. size: item.size,
  55. backgroundColorName: item.backgroundColorName) {
  56. print("button : \(item.title)")
  57. }
  58. }
  59. }
  60. }
  61. }
  62. /// 封装计算器上的所有按键
  63. struct CalculatorButtonPad: View {
  64. /// pad里面是每一行的数据,具体意思看下item类
  65. let pad: [[CalculatorButtonItem]] = [
  66. [.command(.clear), .command(.flip), .command(.percent), .op(.divide)],
  67. [.digit(7), .digit(8), .digit(9), .op(.multipy)],
  68. [.digit(4), .digit(5), .digit(6), .op(.minus)],
  69. [.digit(1), .digit(2), .digit(3), .op(.plus)],
  70. [.digit(0), .dot, .op(.equal)],
  71. ]
  72. var body: some View {
  73. //垂直布局类
  74. VStack(spacing: 8, content: {
  75. //使用foreach添加每一行
  76. ForEach(pad, id: \.self) { row in
  77. CalculatorButtonRow(row: row)//每一行的数据
  78. }
  79. })
  80. }
  81. }

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"
        }
    }

}

image.png

效果:

image.png

代码学习于:

猫神 swifter swiftui与combine 编程