Reputation: 3898
I am trying to create a custom header file to all the ViewControllers in project. The following image is an actual design.
So that I am trying to create Custom view with Xib file as below :
import UIKit
class HamburgrView: UIView {
override init(frame: CGRect) {
// 1. setup any properties here
// 2. call super.init(frame:)
super.init(frame: frame)
// 3. Setup view from .xib file
xibSetup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
xibSetup()
}
override open func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
xibSetup()
}
override func layoutSubviews() {
}
func xibSetup() {
let tempView = loadViewFromNib()
// use bounds not frame or it'll be offset
tempView.frame = bounds
// Make the view stretch with containing view
tempView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
// Adding custom subview on top of our view (over any custom drawing > see note below)
addSubview(tempView)
}
func loadViewFromNib() -> UIView {
let bundle = Bundle(for: type(of:self))
let nib = UINib(nibName: "HamburgrView", bundle: bundle)
// Assumes UIView is top level and only object in CustomView.xib file
let view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView
return view
}
}
We don't know how to draw that Hamburger menu icon with curve and its start position from SafeArealayoutGuide.
I trying one view with x position negative -40 and giving cornerRadius not coming perfect curve like above image.
Output look not good.
My ViewController Code :
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let hamView = HamburgrView(frame: .zero)
self.view.addSubview(hamView)
hamView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
hamView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 0),
hamView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0),
hamView.widthAnchor.constraint(equalToConstant: 120),
hamView.heightAnchor.constraint(equalToConstant: 80)
])
}
As @sandip answer I have changed like below :
func xibSetup() {
let tempView = loadViewFromNib()
// use bounds not frame or it'll be offset
tempView.frame = bounds
// Make the view stretch with containing view
tempView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
// Adding custom subview on top of our view (over any custom drawing > see note below)
addSubview(tempView)
let layer = CAShapeLayer()
layer.path = UIBezierPath.init(arcCenter: CGPoint(x: 0, y: self.center.y), radius: 50, startAngle: -1.5708, endAngle: 1.5708, clockwise: true).cgPath
layer.fillColor = UIColor.red.cgColor
self.layer.addSublayer(layer)
}
Output Looks Below :
Upvotes: 1
Views: 85
Reputation: 20379
Is this what you wanted?
You can easily achieve it with CAShapeLayer
and UIBezierPath
let layer = CAShapeLayer()
layer.path = UIBezierPath.init(arcCenter: CGPoint(x: 0, y: self.view.center.y), radius: 30, startAngle: -1.5708, endAngle: 1.5708, clockwise: true).cgPath
layer.fillColor = UIColor.red.cgColor
view.layer.addSublayer(layer)
In your code change arc centre as x to be zero and y to hamburger view's vertical centre and add it to self.view
Hope it helps
EDIT 1:
As OP has asked for complete code in comment updating the answer
class HamburgrView: UIView {
override init(frame: CGRect) {
// 1. setup any properties here
// 2. call super.init(frame:)
super.init(frame: frame)
// 3. Setup view from .xib file
xibSetup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
xibSetup()
}
override open func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
xibSetup()
}
override func layoutSubviews() {
}
func xibSetup() {
let tempView = loadViewFromNib()
// use bounds not frame or it'll be offset
tempView.frame = bounds
// Make the view stretch with containing view
tempView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
// Adding custom subview on top of our view (over any custom drawing > see note below)
addSubview(tempView)
}
func loadViewFromNib() -> UIView {
let bundle = Bundle(for: type(of:self))
let nib = UINib(nibName: "HamburgrView", bundle: bundle)
// Assumes UIView is top level and only object in CustomView.xib file
let view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView
return view
}
override func didMoveToSuperview() {
super.didMoveToSuperview()
let layer = CAShapeLayer()
layer.path = UIBezierPath.init(arcCenter: CGPoint(x: 0, y: 40), radius: 50, startAngle: -1.5708, endAngle: 1.5708, clockwise: true).cgPath
layer.fillColor = UIColor.red.cgColor
self.layer.addSublayer(layer)
}
}
EDIT 2:
Reason OPs arc coming outside hamburger view is because of wrong arc centre
changing to CGPoint(x: 0, y: 40)
from self.view.center.y
should solve the issue. Updated the code to reflect the same
Why 40?
Because OP is setting height of hamburger view to 80. So 80/2 = 40
Why cant we use bounds.size.height / 2
or self.view.center.y
?
because in didMoveToSuperview OP's constraint has not kicked in yet so it is taking the height view in xib which I don't think is 80 so it sets the arc centre with that value but then your constraint changes height to 80.
Here is final O/P:
Upvotes: 1