为所有 VC 自定义 header UIView?
custom header UIView to all the VC?
我正在尝试为项目中的所有 ViewControllers 创建自定义 header 文件。下图是实际设计。
所以我正在尝试使用 Xib 文件创建自定义视图,如下所示:
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
}
}
我们不知道如何用曲线绘制汉堡包菜单图标及其起始位置 SafeArealayoutGuide。
我尝试了一个 x 位置为负 -40 的视图,并给了 cornerRadius 不像上图那样完美的曲线。
输出看起来不太好。
我的ViewController代码:
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)
])
}
作为@sandip 的回答,我做了如下更改:
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)
}
输出如下所示:
任何想法将不胜感激。
这是你想要的吗?
您可以使用 CAShapeLayer
和 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)
在您的代码中将圆弧中心更改为 x 为零,将 y 更改为汉堡包视图的垂直中心并将其添加到 self.view
希望对您有所帮助
编辑 1:
由于 OP 在更新答案的评论中要求提供完整代码
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)
}
}
编辑 2:
OP 弧线出现在汉堡包视图之外的原因是因为弧线中心错误
从 self.view.center.y
更改为 CGPoint(x: 0, y: 40)
应该可以解决问题。更新了代码以反映相同的内容
为什么是 40?
因为 OP 将汉堡视图的高度设置为 80。所以 80/2 = 40
为什么我们不能使用bounds.size.height / 2
或self.view.center.y
?
因为在 didMoveToSuperview 中 OP 的约束尚未启动,所以它在 xib 中采用高度视图,我认为它不是 80,所以它使用该值设置圆弧中心,但随后你的约束将高度更改为 80。
这是最后的 O/P:
我正在尝试为项目中的所有 ViewControllers 创建自定义 header 文件。下图是实际设计。
所以我正在尝试使用 Xib 文件创建自定义视图,如下所示:
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
}
}
我们不知道如何用曲线绘制汉堡包菜单图标及其起始位置 SafeArealayoutGuide。
我尝试了一个 x 位置为负 -40 的视图,并给了 cornerRadius 不像上图那样完美的曲线。
输出看起来不太好。
我的ViewController代码:
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)
])
}
作为@sandip 的回答,我做了如下更改:
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)
}
输出如下所示:
这是你想要的吗?
您可以使用 CAShapeLayer
和 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)
在您的代码中将圆弧中心更改为 x 为零,将 y 更改为汉堡包视图的垂直中心并将其添加到 self.view
希望对您有所帮助
编辑 1:
由于 OP 在更新答案的评论中要求提供完整代码
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)
}
}
编辑 2:
OP 弧线出现在汉堡包视图之外的原因是因为弧线中心错误
从 self.view.center.y
更改为 CGPoint(x: 0, y: 40)
应该可以解决问题。更新了代码以反映相同的内容
为什么是 40?
因为 OP 将汉堡视图的高度设置为 80。所以 80/2 = 40
为什么我们不能使用bounds.size.height / 2
或self.view.center.y
?
因为在 didMoveToSuperview 中 OP 的约束尚未启动,所以它在 xib 中采用高度视图,我认为它不是 80,所以它使用该值设置圆弧中心,但随后你的约束将高度更改为 80。
这是最后的 O/P: