如何实现Zig-Zag锯齿排布样式的UICollectionView?
实现Zig-Zag锯齿风格UICollectionView的完整方案
你当前仅实现了奇偶cell的背景色区分,缺少cell偏移布局和锯齿边缘绘制两个核心逻辑,按以下步骤调整即可实现目标效果:
步骤1:自定义流式布局实现奇偶行错位
创建自定义ZigZagCollectionLayout,继承自UICollectionViewFlowLayout,重写布局属性方法实现奇偶行的水平偏移:
class ZigZagCollectionLayout: UICollectionViewFlowLayout { override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { let attributes = super.layoutAttributesForElements(in: rect) let cellWidth = (collectionView?.frame.width ?? 0) / 2 // 假设每行2个cell let offsetX = cellWidth / 2 // 奇数行偏移量 attributes?.forEach { attribute in let row = attribute.indexPath.row / 2 // 计算当前cell所在行 if row % 2 != 0 { // 奇数行整体向右偏移半个cell宽度 var frame = attribute.frame frame.origin.x += offsetX attribute.frame = frame } } return attributes } override var collectionViewContentSize: CGSize { let contentSize = super.collectionViewContentSize // 给内容宽度加上偏移量避免右侧cell被截断 return CGSize(width: contentSize.width + (UIScreen.main.bounds.width / 4), height: contentSize.height) } }
初始化UICollectionView时使用该自定义布局即可。
步骤2:实现cell的锯齿边缘效果
补充你自定义cell中setUpCell()方法的逻辑,给viewBG添加上下边缘的锯齿遮罩:
func setUpCell() { viewBG.layer.mask = nil // 先清除旧遮罩避免复用问题 let bezierPath = UIBezierPath() let width = viewBG.bounds.width let height = viewBG.bounds.height let sawtoothWidth: CGFloat = 15 // 单个锯齿的宽度 let sawtoothHeight: CGFloat = 8 // 单个锯齿的高度 // 绘制上边缘锯齿 bezierPath.move(to: .zero) var currentX: CGFloat = 0 while currentX < width { bezierPath.addLine(to: CGPoint(x: currentX + sawtoothWidth/2, y: sawtoothHeight)) bezierPath.addLine(to: CGPoint(x: currentX + sawtoothWidth, y: 0)) currentX += sawtoothWidth } // 绘制右边缘、下边缘 bezierPath.addLine(to: CGPoint(x: width, y: height)) currentX = width while currentX > 0 { bezierPath.addLine(to: CGPoint(x: currentX - sawtoothWidth/2, y: height - sawtoothHeight)) bezierPath.addLine(to: CGPoint(x: currentX - sawtoothWidth, y: height)) currentX -= sawtoothWidth } // 绘制左边缘闭合路径 bezierPath.addLine(to: .zero) bezierPath.close() let shapeLayer = CAShapeLayer() shapeLayer.path = bezierPath.cgPath viewBG.layer.mask = shapeLayer }
最终效果

内容的提问来源于stack exchange,提问作者Kamlesh Shingarakhiya
相关产品推荐
相关产品推荐

