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
相关产品推荐
相关产品推荐

