所以我还没有看到其他有关此的问题。基本上,我以编程方式设置了具有自动布局的UIView。
当我尝试创建UIBezierPath时出现问题:
let circularPath = UIBezierPath(arcCenter: myView.center, radius: (91*(1.2))/2 - (8/2), startAngle: -CGFloat.pi / 2, endAngle: 2 * CGFloat.pi, clockwise: true)
问题是myView.center打印出来:0.0, 0.0
,因为我没有为myView设置CGRect .frame,而是使用了自动布局(如下):
NSLayoutConstraint.activate([
myView.heightAnchor.constraint(equalToConstant: 91),
myView.widthAnchor.constraint(equalToConstant: 91),
myView.centerXAnchor.constraint(equalToSystemSpacingAfter: myButton.centerXAnchor, multiplier: 1),
myView.centerYAnchor.constraint(equalToSystemSpacingBelow: myButton.centerYAnchor, multiplier: 1),
])
还有,也许我应该注意,myView是作为myButton的子视图添加的(尽管这并不重要。)
所以我该如何做这项工作?我怎样才能在UIBezierPath中使用.center(CGPoint类型)?谢谢!
一些观察:
center
属性是当前视图的中心在在超级视图的坐标系内的位置。这不太可能是您想要的。您需要CGPoint(x: myView.bounds.midX, y: myView.bounds.midY)
,它是current视图的中点。
由于使用约束,因此需要将路径的创建推迟到应用约束之后,因为这是设置视图的bounds
的时间。典型的解决方案是实现UIButton
子类,在该子类中,您可以实现layoutSubviews
,并在那里设置路径。
例如,一个简单的圆形按钮可能定义如下:
layoutSubviews
此方法的优点在于:
您的视图控制器没有很多用于渲染圆的代码。
无论渲染大小如何,该方法都可以工作(如果您的约束条件不是固定大小,但可能会响应设备的方向,大小类别等,则很有用。)>
如果需要,因为它是@IBDesignable
class CircleButton: UIButton {
let normalColor: UIColor = .red
let highlightedColor: UIColor = .init(red: 0.5, green: 0, blue: 0, alpha: 1)
lazy var shapeLayer: CAShapeLayer = {
let shapeLayer = CAShapeLayer()
shapeLayer.fillColor = normalColor.cgColor
return shapeLayer
}()
override init(frame: CGRect = .zero) {
super.init(frame: frame)
configure()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
configure()
}
func configure() {
layer.addSublayer(shapeLayer)
}
override func layoutSubviews() {
super.layoutSubviews()
let center = CGPoint(x: bounds.midX, y: bounds.midY)
let radius = min(bounds.height, bounds.width) / 2
shapeLayer.path = UIBezierPath(arcCenter: center, radius: radius, startAngle: 0, endAngle: 2 * .pi, clockwise: true).cgPath
}
override var isHighlighted: Bool {
didSet {
if isHighlighted {
shapeLayer.fillColor = highlightedColor.cgColor
} else {
shapeLayer.fillColor = normalColor.cgColor
}
}
}
}
,所以可以在情节提要/ NIB中进行渲染。
您可以尝试使用边界代替框架。它们可以帮助您提供UIVIew的中心坐标。中心属性是当前视图的中心在超级视图的坐标系内的位置。您可以尝试使用以下代码作为当前视图的中点。