居中对齐 UIView 中的 CAShape 层
Centre Align CAShape layer in a UIView
以下是代码未对齐 UIView 中心的图像,白色。
CAShapeLayer *layer = [CAShapeLayer layer];
layer.anchorPoint=CGPointMake(0.5, 0.5);
layer.path=[UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 75.0, 75.0)].CGPath;
layer.fillColor =[UIColor redColor].CGColor;
[self.shapeView.layer addSublayer:layer];
anchorPoint
不是用来设置CAShapeLayer的位置,用position
代替。
let layer = CAShapeLayer()
layer.borderColor = UIColor.blackColor().CGColor
layer.borderWidth = 100
layer.bounds = CGRectMake(0, 0, 50, 50)
layer.position = myView.center
layer.fillColor = UIColor.redColor().CGColor
view.layer.addSublayer(layer)
编辑
抱歉之前这么粗略的回答,上面的代码可能不能如你所愿,这是我刚出来的正确答案。需要注意的重要一点是:如何绘制椭圆路径确实影响了 CAShapeLayer
的位置
let layer = CAShapeLayer()
myView.layer.addSublayer(layer)
layer.fillColor = UIColor.redColor().CGColor
layer.anchorPoint = CGPointMake(0.5, 0.5)
layer.position = CGPointMake(myView.layer.bounds.midX, myView.layer.bounds.midY)
layer.path = UIBezierPath(ovalInRect: CGRectMake(-75.0 / 2, -75.0 / 2, 75.0, 75.0)).CGPath
来自 Apple 文档,
The oval path is created in a clockwise direction (relative to the default
coordinate system)
换句话说,椭圆路径是从边缘而不是中心绘制的,所以你必须考虑你绘制的椭圆的半径。在您的情况下,您需要这样做:
layer.path = UIBezierPath(ovalInRect: CGRectMake(-75.0 / 2, -75.0 / 2, 75.0, 75.0)).CGPath
现在我们确保绘制路径的中心等于CAShapeLayer
的中心。然后我们可以使用 position
属性 来移动 CAShapeLayer
。下图可以帮助你理解。
CAShapeLayer *layer = [CAShapeLayer layer];
layer.anchorPoint=CGPointMake(0.5, 0.5);
layer.path=[UIBezierPath bezierPathWithOvalInRect:CGRectMake((self.shapeView.frame.size.width/2)-37.5, (self.shapeView.frame.size.height/2)-37.5, 75.0, 75.0)].CGPath;
//37.5 means width & height divided by 2
layer.fillColor =[UIColor redColor].CGColor;
[self.shapeView.layer addSublayer:layer];
对于那些仍然对居中有疑问的人,这种方法对我有用:
1- 设置形状图层框架等于父视图框架。
shapeLayer.frame = view.frame
2-去掉形状图层位置属性.
// shapeLayer.position = CGPoint(x: ,y: )
3- 将贝塞尔曲线路径的 x 和 y 值设置为零。
UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: self.width, height:
self.height))
只有这些就够了,其他的都去掉
======
如果还是不行,试试这个:
@IBDesignable class YourView: UIView {
private var shapeLayer: CAShapeLayer!
override func draw(_ rect: CGRect) {
self.shapeLayer = CAShapeLayer()
self.shapeLayer.path = bezierPath.cgPath
self.shapeLayer.fillColor = UIColor.blue.cgColor
let bezierPathHeight = self.bezierPath.cgPath.boundingBox.height
let bezierPathWidth = self.bezierPath.cgPath.boundingBox.width
self.shapeLayer.setAffineTransform(CGAffineTransform.init(translationX: self.bounds.width / bezierPathWidth, y: self.bounds.height / bezierPathHeight))
self.shapeLayer.setAffineTransform(CGAffineTransform.init(scaleX: self.bounds.width / bezierPathHeight, y: self.bounds.height / bezierPathHeight))
self.layer.addSublayer(self.shapeLayer)
}
我遇到过这样的情况。最终分辨率为shapeLayer.needsDisplayOnBoundsChange = true
并在layoutSubviews
中更新CAShapeLayer frame,CenteredAlignShapeView可以在使用Auto Layout时进行调整。
class CenteredAlignShapeView: UIView {
public let dot = CAShapeLayer()
init() {
super.init(frame: .zero)
dot.needsDisplayOnBoundsChange = true
layer.insertSublayer(dot, at: 0)
dot.fillColor = UIColor.red.cgColor
}
override func layoutSubviews() {
super.layoutSubviews()
dot.frame = bounds
let circlePath = UIBezierPath(arcCenter: CGPoint(x: bounds.width/2, y: bounds.height/2), radius: 4, startAngle: 0, endAngle: CGFloat.pi*2, clockwise: true)
dot.path = circlePath.cgPath
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
以下是代码未对齐 UIView 中心的图像,白色。
CAShapeLayer *layer = [CAShapeLayer layer];
layer.anchorPoint=CGPointMake(0.5, 0.5);
layer.path=[UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 75.0, 75.0)].CGPath;
layer.fillColor =[UIColor redColor].CGColor;
[self.shapeView.layer addSublayer:layer];
anchorPoint
不是用来设置CAShapeLayer的位置,用position
代替。
let layer = CAShapeLayer()
layer.borderColor = UIColor.blackColor().CGColor
layer.borderWidth = 100
layer.bounds = CGRectMake(0, 0, 50, 50)
layer.position = myView.center
layer.fillColor = UIColor.redColor().CGColor
view.layer.addSublayer(layer)
编辑
抱歉之前这么粗略的回答,上面的代码可能不能如你所愿,这是我刚出来的正确答案。需要注意的重要一点是:如何绘制椭圆路径确实影响了 CAShapeLayer
let layer = CAShapeLayer()
myView.layer.addSublayer(layer)
layer.fillColor = UIColor.redColor().CGColor
layer.anchorPoint = CGPointMake(0.5, 0.5)
layer.position = CGPointMake(myView.layer.bounds.midX, myView.layer.bounds.midY)
layer.path = UIBezierPath(ovalInRect: CGRectMake(-75.0 / 2, -75.0 / 2, 75.0, 75.0)).CGPath
来自 Apple 文档,
The oval path is created in a clockwise direction (relative to the default coordinate system)
换句话说,椭圆路径是从边缘而不是中心绘制的,所以你必须考虑你绘制的椭圆的半径。在您的情况下,您需要这样做:
layer.path = UIBezierPath(ovalInRect: CGRectMake(-75.0 / 2, -75.0 / 2, 75.0, 75.0)).CGPath
现在我们确保绘制路径的中心等于CAShapeLayer
的中心。然后我们可以使用 position
属性 来移动 CAShapeLayer
。下图可以帮助你理解。
CAShapeLayer *layer = [CAShapeLayer layer];
layer.anchorPoint=CGPointMake(0.5, 0.5);
layer.path=[UIBezierPath bezierPathWithOvalInRect:CGRectMake((self.shapeView.frame.size.width/2)-37.5, (self.shapeView.frame.size.height/2)-37.5, 75.0, 75.0)].CGPath;
//37.5 means width & height divided by 2
layer.fillColor =[UIColor redColor].CGColor;
[self.shapeView.layer addSublayer:layer];
对于那些仍然对居中有疑问的人,这种方法对我有用:
1- 设置形状图层框架等于父视图框架。
shapeLayer.frame = view.frame
2-去掉形状图层位置属性.
// shapeLayer.position = CGPoint(x: ,y: )
3- 将贝塞尔曲线路径的 x 和 y 值设置为零。
UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: self.width, height:
self.height))
只有这些就够了,其他的都去掉
======
如果还是不行,试试这个:
@IBDesignable class YourView: UIView {
private var shapeLayer: CAShapeLayer!
override func draw(_ rect: CGRect) {
self.shapeLayer = CAShapeLayer()
self.shapeLayer.path = bezierPath.cgPath
self.shapeLayer.fillColor = UIColor.blue.cgColor
let bezierPathHeight = self.bezierPath.cgPath.boundingBox.height
let bezierPathWidth = self.bezierPath.cgPath.boundingBox.width
self.shapeLayer.setAffineTransform(CGAffineTransform.init(translationX: self.bounds.width / bezierPathWidth, y: self.bounds.height / bezierPathHeight))
self.shapeLayer.setAffineTransform(CGAffineTransform.init(scaleX: self.bounds.width / bezierPathHeight, y: self.bounds.height / bezierPathHeight))
self.layer.addSublayer(self.shapeLayer)
}
我遇到过这样的情况。最终分辨率为shapeLayer.needsDisplayOnBoundsChange = true
并在layoutSubviews
中更新CAShapeLayer frame,CenteredAlignShapeView可以在使用Auto Layout时进行调整。
class CenteredAlignShapeView: UIView {
public let dot = CAShapeLayer()
init() {
super.init(frame: .zero)
dot.needsDisplayOnBoundsChange = true
layer.insertSublayer(dot, at: 0)
dot.fillColor = UIColor.red.cgColor
}
override func layoutSubviews() {
super.layoutSubviews()
dot.frame = bounds
let circlePath = UIBezierPath(arcCenter: CGPoint(x: bounds.width/2, y: bounds.height/2), radius: 4, startAngle: 0, endAngle: CGFloat.pi*2, clockwise: true)
dot.path = circlePath.cgPath
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}