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

Swift中如何将UIView网格点击位置映射至二维数组行列

嘿,这个需求我之前做类似棋盘类项目时碰到过,分享几个比直接用touchesBegin更可靠的方案给你:

方案1:给网格视图设置Tag(最简单直接的静态网格方案)

因为你的网格是固定10×10,我们可以给每个单元格视图设置一个唯一的Tag,用行号×10 + 列号的规则生成,点击时通过Tag反推出行列索引。

代码示例:

// 假设container是承载网格的父视图
let gridCount = 10
let cellSize = container.bounds.width / CGFloat(gridCount)

// 创建网格
for row in 0..<gridCount {
    for column in 0..<gridCount {
        let cellFrame = CGRect(
            x: CGFloat(column) * cellSize,
            y: CGFloat(row) * cellSize,
            width: cellSize,
            height: cellSize
        )
        let cell = UIImageView(frame: cellFrame)
        cell.tag = row * gridCount + column // 核心:设置唯一Tag
        cell.isUserInteractionEnabled = true // UIImageView默认关闭交互,必须打开
        // 添加点击手势
        let tap = UITapGestureRecognizer(target: self, action: #selector(onCellTapped(_:)))
        cell.addGestureRecognizer(tap)
        // 其他样式/图片设置...
        container.addSubview(cell)
    }
}

// 处理点击事件
@objc private func onCellTapped(_ gesture: UITapGestureRecognizer) {
    guard let cell = gesture.view else { return }
    let row = cell.tag / 10
    let column = cell.tag % 10
    // 更新二维数组
    yourTwoDimensionalArray[row][column] = 1
    // 这里可以同步更新单元格的图片状态
}

这个方案的优势是实现成本极低,适合固定尺寸的静态网格,几乎不会出错。

方案2:使用UICollectionView(最具扩展性的原生方案)

如果你的网格未来可能需要滚动、复用单元格,或者调整行列数,UICollectionView是iOS原生的最佳选择,它的代理方法可以直接返回点击位置的索引。

代码示例:

// 初始化CollectionView和布局
let layout = UICollectionViewFlowLayout()
let cellSize = container.bounds.width / 10
layout.itemSize = CGSize(width: cellSize, height: cellSize)
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0

let collectionView = UICollectionView(frame: container.bounds, collectionViewLayout: layout)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "GridCell")
container.addSubview(collectionView)

// 实现数据源和代理
extension YourViewController: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 100 // 10×10的总单元格数
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "GridCell", for: indexPath)
        // 设置单元格的图片或样式,比如根据数组状态显示不同图片
        let row = indexPath.item / 10
        let column = indexPath.item % 10
        if yourTwoDimensionalArray[row][column] == 1 {
            (cell.contentView.subviews.first as? UIImageView)?.image = selectedImage
        }
        return cell
    }
}

extension YourViewController: UICollectionViewDelegate {
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let row = indexPath.item / 10
        let column = indexPath.item % 10
        yourTwoDimensionalArray[row][column] = 1
        // 刷新对应单元格的UI
        collectionView.reloadItems(at: [indexPath])
    }
}

这个方案的优势是自带单元格复用机制,性能更好,后续扩展功能(比如添加动画、调整网格大小)也更方便。

方案3:优化你的touchesBegin方案(无额外依赖的轻量方案)

如果你不想用Tag或CollectionView,也可以优化原始的坐标计算方法,避免浮点误差导致的索引错误:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    super.touchesBegan(touches, with: event)
    guard let touch = touches.first, let container = self.gridContainerView else { return }
    let touchPoint = touch.location(in: container)
    let gridCount = 10
    let cellSize = container.bounds.width / CGFloat(gridCount)
    
    // 用floor确保浮点计算不会出现越界(比如9.999被当成10)
    let column = Int(floor(touchPoint.x / cellSize))
    let row = Int(floor(touchPoint.y / cellSize))
    
    // 边界检查,防止点击到网格外的区域导致数组越界
    guard row >= 0, row < gridCount, column >= 0, column < gridCount else { return }
    
    yourTwoDimensionalArray[row][column] = 1
    // 更新对应单元格的图片
    let targetCell = container.subviews[row * gridCount + column] as? UIImageView
    targetCell?.image = selectedImage
}

这个方法要注意确保容器视图的frame是准确的,并且一定要加边界检查,避免数组越界崩溃。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:12:41