Swift 3视图绘制网格:解决线条超出视图边界问题
解决Swift 3视图中网格线条超出框架的问题
你遇到的线条超出视图框架的问题,本质是因为UIBezierPath的线条是居中绘制的——比如你设置了lineWidth = 5.0,这条线会向路径的两侧各延伸2.5个点,所以原本贴着视图边缘的线条就会超出边界了。
先看你提供的效果示意图:
网格线条超出视图框架
你的原始代码:
path = UIBezierPath() path.lineWidth = 5.0 for index in 1...Int(gridWidthMultiple) - 1 { let start = CGPoint(x: CGFloat(index) * gridWidth, y: 0) let end = CGPoint(x: CGFloat(index) * gridWidth, y: bounds.height) path.move(to: start) path.addLine(to: end) } let numberOfRows: Int = Int(self.frame.size.height)/Int(gridWidth); for index in 1...numberOfRows { let start = CGPoint(x: 0.0, y: gridWidth * CGFloat(index)) let end = CGPoint(x: self.frame.size.width, y: start.y) path.move(to: start) path.addLine(to: end) } self.setNeedsDisplay()
修复方案
我们需要把绘制的边界向内偏移线条宽度的一半,同时优化一些细节(比如用bounds替代frame,避免整数除法的精度问题),修改后的代码如下:
path = UIBezierPath() path.lineWidth = 5.0 // 计算线条的偏移量,让线条居中在视图内部 let lineOffset = path.lineWidth / 2.0 // 绘制竖线 for index in 1..<Int(gridWidthMultiple) { let xPos = CGFloat(index) * gridWidth // 起始和结束的y坐标要加上偏移量,避免超出顶部和底部 let start = CGPoint(x: xPos, y: lineOffset) let end = CGPoint(x: xPos, y: bounds.height - lineOffset) path.move(to: start) path.addLine(to: end) } // 绘制横线:用ceil处理高度计算,避免因整数除法丢失最后一行 let numberOfRows = Int(ceil(bounds.height / gridWidth)) for index in 1..<numberOfRows { let yPos = gridWidth * CGFloat(index) // 起始和结束的x坐标要加上偏移量,避免超出左侧和右侧 let start = CGPoint(x: lineOffset, y: yPos) let end = CGPoint(x: bounds.width - lineOffset, y: yPos) path.move(to: start) path.addLine(to: end) } self.setNeedsDisplay()
关键修改点说明
- 线条偏移量:通过
lineOffset = path.lineWidth / 2.0计算出需要向内缩的距离,让线条的边缘刚好贴合视图的边界,不会向外溢出。 - 替换frame为bounds:
bounds是视图自身的坐标系,比frame更可靠(尤其是视图有变换的时候)。 - 优化行数计算:用
ceil(bounds.height / gridWidth)代替整数除法,确保即使高度不能被gridWidth整除,也能正确计算出需要的行数。 - 循环范围调整:把
1...Int(gridWidthMultiple)-1改成1..<Int(gridWidthMultiple),写法更简洁且逻辑一致。
这样修改后,网格线条就会完全被限制在视图的框架内啦!
内容的提问来源于stack exchange,提问作者BizDev
相关产品推荐
相关产品推荐

