SwiftUI中如何将图片分割为多个子图或显示局部区域?
SwiftUI拼图游戏:实现原图局部区域显示的两种方案
方案一:Offset + Clipped 实时裁剪(纯SwiftUI)
核心思路:通过偏移原图,把目标局部区域移到固定大小的可视容器内,再裁剪掉超出部分。
比如要显示原图中间(x=100, y=100)的100x100区域,代码如下:
Image("your-300x300-image") .resizable() .frame(width: 300, height: 300) // 先还原原图的实际尺寸 .offset(x: -100, y: -100) // 将目标区域偏移到容器的可视范围内 .frame(width: 100, height: 100) // 设置最终显示的子图大小 .clipped()
如果要遍历生成9张子图,只需要根据行列计算偏移量:
ForEach(0..<3, id: \.self) { row in HStack { ForEach(0..<3, id: \.self) { column in Image("your-300x300-image") .resizable() .frame(width: 300, height: 300) .offset(x: -CGFloat(column * 100), y: -CGFloat(row * 100)) .frame(width: 100, height: 100) .clipped() } } }
方案二:预生成子图(基于CGImage裁剪)
如果需要提前生成所有子图(比如做打乱、状态管理更方便),可以直接裁剪原图的指定区域生成独立的小图:
func generateSubImage(row: Int, column: Int) -> Image? { guard let sourceImage = UIImage(named: "your-300x300-image") else { return nil } // 计算要裁剪的区域 let cropRect = CGRect( x: CGFloat(column * 100), y: CGFloat(row * 100), width: 100, height: 100 ) // 裁剪并转成SwiftUI Image guard let croppedCGImage = sourceImage.cgImage?.cropping(to: cropRect) else { return nil } return Image(uiImage: UIImage(cgImage: croppedCGImage)) }
调用时直接generateSubImage(row: 1, column: 1)就能拿到中间的子图,后续可以把这些子图存在数组里,方便做拼图的打乱和拼接逻辑。
额外提示
- 可以用二维数组记录每个拼图位置对应的子图索引,实现打乱功能
- 给每个子图添加
DragGesture,实现拖拽交换位置的交互
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

