在 UIView 中居中 CAShapeLayer?
Centering a CAShapeLayer within a UIView?
像这道题大概有 5 个以上,但其中 none 个解决了问题。
我想在一个视图上以一个圆为中心。尽管通过类似的问题尝试了各种方法,但它并没有发生。
我不确定是否会发生这种情况,因为我设置了 translatesAutoresizingMaskIntoConstraints = false
。我试着玩弄形状层的中心点和锚点,但疯狂的行为发生了。我试着把这段代码放在 viewDidLayouSubviews
中。没用。我还能做什么?
colorSizeGuide
是我试图将图层居中的视图。
func setupConstraints() {
// other constraints set up here
colorSizeGuide.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
colorSizeGuide.topAnchor.constraint(equalTo: view.topAnchor, constant: 30).isActive = true
colorSizeGuide.widthAnchor.constraint(equalToConstant: 30).isActive = true
colorSizeGuide.heightAnchor.constraint(equalToConstant: 30).isActive = true
}
func setupColorSizeGuide() {
shape.path = UIBezierPath(ovalIn: colorSizeGuide.frame).cgPath
shape.position = self.colorSizeGuide.center
shape.anchorPoint = CGPoint(x: 0.5, y: 0.5)
shape.strokeColor = (UIColor.black).cgColor
shape.fillColor = (UIColor.clear).cgColor
shape.lineWidth = 1.0
colorSizeGuide.layer.addSublayer(shape)
}
您可以选择几个选项。
- 如果您不在滚动环境中(例如
tableView
),请在视图上使用矩形宽度一半的角半径,然后视图将被裁剪为圆形 - 这不是特别快或可定制,但它完成了工作。
游乐场代码:
import UIKit
import PlaygroundSupport
let frame: CGRect = CGRect(x: 0, y: 0, width: 100, height: 100)
let view: UIView = UIView(frame: frame)
view.backgroundColor = .magenta
view.layer.cornerRadius = frame.size.width / 2
PlaygroundPage.current.liveView = view
- 您可以让您的自定义
UIView
子类在其中实现 layerClass
方法和 return CAShapeLayer
。这意味着您视图的 self.layer
实际上是一个形状图层。您可以在那里设置一个圆圈的路径,然后就可以了。如果你想让它在视图中居中,只需确保在定义 UIBezierPath
. 时使用视图的边界坐标
游乐场代码:
import UIKit
import PlaygroundSupport
let frame: CGRect = CGRect(x: 0, y: 0, width: 100, height: 100)
let view: UIView = UIView(frame: frame)
PlaygroundPage.current.liveView = view
class ShapeView: UIView {
override class var layerClass: AnyClass { return CAShapeLayer.self }
override init(frame: CGRect) {
super.init(frame: frame)
(layer as? CAShapeLayer)?.fillColor = UIColor.red.cgColor
(layer as? CAShapeLayer)?.strokeColor = UIColor.green.cgColor
(layer as? CAShapeLayer)?.path = UIBezierPath(ovalIn: frame).cgPath
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
let sv = ShapeView(frame: frame)
view.addSubview(sv)
- 通过执行
CAShapeLayer.init
创建一个非视图形状图层。将你的视图放在它的 layoutSubviews
方法中(如果你在视图控制器中这样做,则为 viewDidLayoutSubviews
)并为形状层设置一个合适的框架,就像它是一个视图一样。
游乐场代码:
import UIKit
import PlaygroundSupport
let frame: CGRect = CGRect(x: 0, y: 0, width: 100, height: 100)
let smallFrame: CGRect = CGRect(x: 0, y: 0, width: 10, height: 10)
let view: UIView = UIView(frame: frame)
view.backgroundColor = .magenta
PlaygroundPage.current.liveView = view
let sl = CAShapeLayer()
sl.path = UIBezierPath(ovalIn: smallFrame).cgPath
sl.fillColor = UIColor.red.cgColor
sl.strokeColor = UIColor.green.cgColor
sl.frame.origin.x = 30
sl.frame.origin.y = 30
view.layer.addSublayer(sl)
像这道题大概有 5 个以上,但其中 none 个解决了问题。
我想在一个视图上以一个圆为中心。尽管通过类似的问题尝试了各种方法,但它并没有发生。
我不确定是否会发生这种情况,因为我设置了 translatesAutoresizingMaskIntoConstraints = false
。我试着玩弄形状层的中心点和锚点,但疯狂的行为发生了。我试着把这段代码放在 viewDidLayouSubviews
中。没用。我还能做什么?
colorSizeGuide
是我试图将图层居中的视图。
func setupConstraints() {
// other constraints set up here
colorSizeGuide.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
colorSizeGuide.topAnchor.constraint(equalTo: view.topAnchor, constant: 30).isActive = true
colorSizeGuide.widthAnchor.constraint(equalToConstant: 30).isActive = true
colorSizeGuide.heightAnchor.constraint(equalToConstant: 30).isActive = true
}
func setupColorSizeGuide() {
shape.path = UIBezierPath(ovalIn: colorSizeGuide.frame).cgPath
shape.position = self.colorSizeGuide.center
shape.anchorPoint = CGPoint(x: 0.5, y: 0.5)
shape.strokeColor = (UIColor.black).cgColor
shape.fillColor = (UIColor.clear).cgColor
shape.lineWidth = 1.0
colorSizeGuide.layer.addSublayer(shape)
}
您可以选择几个选项。
- 如果您不在滚动环境中(例如
tableView
),请在视图上使用矩形宽度一半的角半径,然后视图将被裁剪为圆形 - 这不是特别快或可定制,但它完成了工作。
游乐场代码:
import UIKit
import PlaygroundSupport
let frame: CGRect = CGRect(x: 0, y: 0, width: 100, height: 100)
let view: UIView = UIView(frame: frame)
view.backgroundColor = .magenta
view.layer.cornerRadius = frame.size.width / 2
PlaygroundPage.current.liveView = view
- 您可以让您的自定义
UIView
子类在其中实现layerClass
方法和 returnCAShapeLayer
。这意味着您视图的self.layer
实际上是一个形状图层。您可以在那里设置一个圆圈的路径,然后就可以了。如果你想让它在视图中居中,只需确保在定义UIBezierPath
. 时使用视图的边界坐标
游乐场代码:
import UIKit
import PlaygroundSupport
let frame: CGRect = CGRect(x: 0, y: 0, width: 100, height: 100)
let view: UIView = UIView(frame: frame)
PlaygroundPage.current.liveView = view
class ShapeView: UIView {
override class var layerClass: AnyClass { return CAShapeLayer.self }
override init(frame: CGRect) {
super.init(frame: frame)
(layer as? CAShapeLayer)?.fillColor = UIColor.red.cgColor
(layer as? CAShapeLayer)?.strokeColor = UIColor.green.cgColor
(layer as? CAShapeLayer)?.path = UIBezierPath(ovalIn: frame).cgPath
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
let sv = ShapeView(frame: frame)
view.addSubview(sv)
- 通过执行
CAShapeLayer.init
创建一个非视图形状图层。将你的视图放在它的layoutSubviews
方法中(如果你在视图控制器中这样做,则为viewDidLayoutSubviews
)并为形状层设置一个合适的框架,就像它是一个视图一样。
游乐场代码:
import UIKit
import PlaygroundSupport
let frame: CGRect = CGRect(x: 0, y: 0, width: 100, height: 100)
let smallFrame: CGRect = CGRect(x: 0, y: 0, width: 10, height: 10)
let view: UIView = UIView(frame: frame)
view.backgroundColor = .magenta
PlaygroundPage.current.liveView = view
let sl = CAShapeLayer()
sl.path = UIBezierPath(ovalIn: smallFrame).cgPath
sl.fillColor = UIColor.red.cgColor
sl.strokeColor = UIColor.green.cgColor
sl.frame.origin.x = 30
sl.frame.origin.y = 30
view.layer.addSublayer(sl)