You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift新手求助:如何在入门计算器App中显示数字网格?

Swift简易计算器数字网格实现方案

用SwiftUI实现(推荐新手)

SwiftUI的LazyVGrid是实现数字网格最便捷的方式,代码简洁且易维护,以下是完整示例:

import SwiftUI

struct CalculatorView: View {
    // 定义计算器数字及符号数组,按网格顺序排列
    private let buttonTitles = [
        "7", "8", "9", "/",
        "4", "5", "6", "*",
        "1", "2", "3", "-",
        "0", ".", "=", "+"
    ]
    
    // 定义网格布局:每行4个等宽按钮
    private let gridItems = [
        GridItem(.flexible()),
        GridItem(.flexible()),
        GridItem(.flexible()),
        GridItem(.flexible())
    ]
    
    var body: some View {
        LazyVGrid(columns: gridItems, spacing: 12) {
            ForEach(buttonTitles, id: \.self) { title in
                Button(action: {
                    // 这里添加按钮点击逻辑,比如更新显示文本
                    print("点击了:\(title)")
                }) {
                    Text(title)
                        .font(.system(size: 28, weight: .medium))
                        .frame(maxWidth: .infinity, maxHeight: .infinity)
                        .background(Color.gray.opacity(0.2))
                        .cornerRadius(8)
                }
            }
        }
        .padding()
        .frame(maxHeight: .infinity, alignment: .bottom) // 让网格固定在底部,符合计算器布局
    }
}

struct CalculatorView_Previews: PreviewProvider {
    static var previews: some View {
        CalculatorView()
    }
}

常见问题排查

  • 如果网格布局混乱:检查GridItem的设置,确保每行数量和数组元素总数匹配;调整spacing值避免按钮重叠。
  • 按钮大小不一致:给Text添加.frame(maxWidth: .infinity, maxHeight: .infinity)确保每个按钮占满网格单元。

用UIKit实现

如果习惯用UIKit,可通过UICollectionView实现,以下是核心代码:

import UIKit

class CalculatorViewController: UIViewController {
    private let buttonTitles = [
        "7", "8", "9", "/",
        "4", "5", "6", "*",
        "1", "2", "3", "-",
        "0", ".", "=", "+"
    ]
    
    private lazy var collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        // 计算每个item的大小:屏幕宽度减去左右padding和间距,分成4列
        let itemWidth = (view.bounds.width - 40 - 3*12)/4
        layout.itemSize = CGSize(width: itemWidth, height: itemWidth)
        layout.minimumInteritemSpacing = 12
        layout.minimumLineSpacing = 12
        layout.sectionInset = UIEdgeInsets(top: 0, left: 20, bottom: 20, right: 20)
        
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.backgroundColor = .white
        collectionView.register(CalculatorButtonCell.self, forCellWithReuseIdentifier: CalculatorButtonCell.identifier)
        collectionView.dataSource = self
        collectionView.delegate = self
        return collectionView
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        setupLayout()
    }
    
    private func setupLayout() {
        view.addSubview(collectionView)
        NSLayoutConstraint.activate([
            collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            collectionView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.6) // 占屏幕60%高度
        ])
    }
}

extension CalculatorViewController: UICollectionViewDataSource, UICollectionViewDelegate {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        buttonTitles.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CalculatorButtonCell.identifier, for: indexPath) as? CalculatorButtonCell else {
            return UICollectionViewCell()
        }
        cell.setTitle(buttonTitles[indexPath.item])
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let title = buttonTitles[indexPath.item]
        print("点击了:\(title)")
    }
}

// 自定义按钮Cell
class CalculatorButtonCell: UICollectionViewCell {
    static let identifier = "CalculatorButtonCell"
    
    private let button: UIButton = {
        let button = UIButton(type: .system)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.titleLabel?.font = UIFont.systemFont(ofSize: 28, weight: .medium)
        button.backgroundColor = UIColor.gray.withAlphaComponent(0.2)
        button.layer.cornerRadius = 8
        return button
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        contentView.addSubview(button)
        NSLayoutConstraint.activate([
            button.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
            button.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
            button.topAnchor.constraint(equalTo: contentView.topAnchor),
            button.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
        ])
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func setTitle(_ title: String) {
        button.setTitle(title, for: .normal)
    }
}

常见问题排查

  • 按钮显示不全:检查itemSize的计算是否正确,确保考虑了间距和内边距;避免硬编码宽度,尽量用屏幕宽度动态计算。
  • Cell注册失败:确保reuseIdentifier和注册、复用的标识一致。

内容的提问来源于stack exchange,提问作者arjun dhindsa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 17:42:49