In my project I want to add a line to a UIView
(this UIView
uses auto layout).
I'm using UIBezierPath
and CAShapeLayer
to draw the line.
This is my code:
let myView = UIView()
self.view.addSubView(myView)
myView.translatesAutoresizingMaskIntoConstraints = false
myView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
myView.heightAnchor.constraint(equalToConstant: 40).isActive = true
myView.widthAnchor.constraint(equalToConstant: 100).isActive = true
myView.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
let path = UIBezierPath()
path.move(to: CGPoint(x: 0, y: myView.frame.height/2))
path.addLine(to: CGPoint(x: myView.frame.width, y: myView.frame.height/2))
let shapeLayer = CAShapeLayer()
shapeLayer.path = path.cgPath
shapeLayer.strokeColor = UIColor.black.cgColor
shapeLayer.lineWidth = 11.0
myView.layer.addSublayer(shapeLayer)
But my problem is no line shows in viewController. When I use this code everything is OK and the line shows perfectly:
let myView = UIView(frame: CGRect(x: 0, y: 160, width: 100, height: 40))
self.view.addSubView(myView)
How can I solve this problem? I must use auto layout.
Your best bet is to use a custom UIView
subclass and set your layer's path in layoutSubviews()
. That way you get the proper frame when needed.
Here's a simple example:
class LineView: UIView {
let shapeLayer: CAShapeLayer = CAShapeLayer()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() -> Void {
layer.addSublayer(shapeLayer)
shapeLayer.strokeColor = UIColor.black.cgColor
shapeLayer.lineWidth = 11.0
}
override func layoutSubviews() {
super.layoutSubviews()
let path = UIBezierPath()
path.move(to: CGPoint(x: 0, y: bounds.midY))
path.addLine(to: CGPoint(x: bounds.maxX, y: bounds.midY))
shapeLayer.path = path.cgPath
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let myView = LineView()
myView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(myView)
NSLayoutConstraint.activate([
myView.topAnchor.constraint(equalTo: self.view.topAnchor),
myView.heightAnchor.constraint(equalToConstant: 40),
myView.widthAnchor.constraint(equalToConstant: 100),
myView.rightAnchor.constraint(equalTo: self.view.rightAnchor),
])
// if you want to see the frame of myView
//myView.backgroundColor = .yellow
}
}
Result - with yellow background so we can see the frame, and with your constraints (you probably want to use safeArea...):