如何获取已使用自动布局设置的UIView的中心点(CGPoint)

问题描述 投票:1回答:2

所以我还没有看到其他有关此的问题。基本上,我以编程方式设置了具有自动布局的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类型)?谢谢!

ios swift xcode autolayout uibezierpath
2个回答
2
投票

一些观察:

  1. center属性是当前视图的中心在在超级视图的坐标系内的位置。这不太可能是您想要的。您需要CGPoint(x: myView.bounds.midX, y: myView.bounds.midY),它是current视图的中点。

  2. 由于使用约束,因此需要将路径的创建推迟到应用约束之后,因为这是设置视图的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中进行渲染。


0
投票

您可以尝试使用边界代替框架。它们可以帮助您提供UIVIew的中心坐标。中心属性是当前视图的中心在超级视图的坐标系内的位置。您可以尝试使用以下代码作为当前视图的中点。

© www.soinside.com 2019 - 2024. All rights reserved.