我想创建自定义的平行四边形视图中使用UIBezierPath
,但没有得到一个完美的一个。
以下是我的自定义视图代码
class CustomView: UIView {
override func draw(_ rect: CGRect) {
let offset = 60.0;
let path = UIBezierPath()
path.move(to: CGPoint(x: self.frame.origin.x + CGFloat(offset), y: self.frame.origin.y))
path.addLine(to: CGPoint(x: self.frame.width + self.frame.origin.x , y: self.frame.origin.y))
path.addLine(to: CGPoint(x: self.frame.origin.x + self.frame.width - CGFloat(offset) , y: self.frame.origin.y + self.frame.height))
path.addLine(to: CGPoint(x: self.frame.origin.x, y: self.frame.origin.y + self.frame.height))
// Close the path. This will create the last line automatically.
path.close()
UIColor.red.setFill()
path.fill()
let shapeLayer = CAShapeLayer()
shapeLayer.path = path.cgPath
self.layer.mask = shapeLayer;
}
}
我创建使用视图
let customView = CustomView()
customView.frame = CGRect(origin: CGPoint(x: 10, y: 20), size: CGSize(width: 250, height: 250))
self.view.addSubview(customView)
但我得到了这样的观点,这是不是一个完美的平行四边形。
问题是frame
内使用draw(_:)
的。问题是,frame
是“规模和它的父坐标系统视图的位置”(强调)。你怎么这个视图中呈现此形状大体无关与在此视图位于它的父。如果这种观点并不正好是0,它的父为0,你可以体验种植。
但不要用rect
参数,无论是。 “你的图绘第一次,这个矩形通常是您的视图的整个可视范围。然而,在随后的绘图操作,矩形可以指定你的观点的一部分。”你有危险,如果操作系统决定只需要更新您的CustomView
的一部分形状从根本上改变。
使用bounds
,相反,这是鉴于自己的坐标系统相同。而且,使用minX
,minY
,maxX
和maxY
简化了代码一点。
@IBDesignable
class CustomView: UIView {
@IBInspectable var offset: CGFloat = 60 { didSet { setNeedsDisplay() } }
@IBInspectable var fillColor: UIColor = .red { didSet { setNeedsDisplay() } }
override func draw(_ rect: CGRect) {
let path = UIBezierPath()
path.move(to: CGPoint(x: bounds.minX + offset, y: bounds.minY))
path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.minY))
path.addLine(to: CGPoint(x: bounds.maxX - offset, y: bounds.maxY))
path.addLine(to: CGPoint(x: bounds.minX, y: bounds.maxY))
// Close the path. This will create the last line automatically.
path.close()
fillColor.setFill()
path.fill()
}
}
顺便说一句,我不设置屏蔽。如果你的动画,它似乎可能是低效的不断重置面具每次draw
被调用。我个人正好被设置为.clear
视图的背景颜色。但是,这不相关的直接的问题。
如@Losiowaty所暗示的,数学为关闭,所述右上角延伸超出帧的边界。 (不知道为什么clipToBounds =虚假不工作;但是这只是一个调试建议 - 不是一个解决方案)。尝试这个:
class CustomView: UIView {
override func draw(_ rect: CGRect) {
let offset: CGFloat = 60.0;
let path = UIBezierPath()
let width = self.bounds.width - offset
let upperLeftPoint = CGPoint(x: self.bounds.origin.x + offset, y: self.bounds.origin.y)
let upperRightPoint = CGPoint(x: self.bounds.origin.x + width, y: self.bounds.origin.y)
let lowerRightPoint = CGPoint(x: width - offset, y: self.bounds.size.height)
let lowerLeftPoint = CGPoint(x: self.bounds.origin.x, y: self.bounds.size.height)
path.move(to: upperLeftPoint)
path.addLine(to: upperRightPoint)
path.addLine(to: lowerRightPoint)
path.addLine(to: lowerLeftPoint)
path.addLine(to: upperLeftPoint)
// Close the path. This will create the last line automatically.
path.close()
UIColor.red.setFill()
path.fill()
let shapeLayer = CAShapeLayer()
shapeLayer.path = path.cgPath
self.layer.mask = shapeLayer;
}
}