IOS 22 自定义标题栏(Toolbar)
标题栏实现效果
实现逻辑
自定义标题栏,我们可以基于系统NavigationBar定制,也可以使用控件完全自定义。本文使用控件完全自定义来实现自定义标题栏效果。
SuperToolbarView
创建一个自定义控件SuperToolbarView,可以把SuperToolbarView分成左中右三个部分;创建左中右布局,添加到SuperToolbarView中;对外提供相应的方法,将添加到左中右布局的方法暴露出去,最后将SuperToolbarView添加到界面。
1)SuperToolbarView继承自TGRelativeLayout布局
class SuperToolbarView : TGRelativeLayout{
}
2)初始化SuperToolbarView,必须要重写required init?(coder: NSCoder) {},便于在可视化布局中使用。
class SuperToolbarView : TGRelativeLayout{
init() {
super.init(frame: CGRect.zero)
initViews()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
initViews()
}
func initViews(){
}
}
3)使用懒加载创建左中右和标题布局
class SuperToolbarView : TGRelativeLayout{
init() {
super.init(frame: CGRect.zero)
initViews()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
initViews()
}
func initViews(){
}
lazy var leftContainer: TGLinearLayout = {
let r = TGLinearLayout(.horz)
r.tg_space = PADDING_MEDDLE
r.tg_gravity = TGGravity.vert.center
r.tg_leading.equal(12)
r.tg_trailing.equal(centerContainer.tg_leading).offset(PADDING_MEDDLE)
r.tg_height.equal(.fill)
return r
}()
lazy var centerContainer: TGLinearLayout = {
let r = TGLinearLayout(.horz)
r.tg_width.equal(.wrap)
r.tg_height.equal(.fill)
r.tg_gravity = TGGravity.vert.center
r.tg_centerX.equal(0)
r.tg_centerY.equal(0)
return r
}()
private lazy var rightContainer: TGLinearLayout = {
let r = TGLinearLayout(.horz)
r.tg_space = PADDING_MEDDLE
r.tg_gravity = [TGGravity.vert.center,TGGravity.horz.right]
r.tg_trailing.equal(12)
r.tg_leading.equal(centerContainer.tg_trailing).offset(PADDING_MEDDLE)
r.tg_height.equal(.fill)
return r
}()
lazy var titleView: UILabel = {
let result=UILabel()
result.tg_width.equal(SCREEN_WIDTH - 150)
result.tg_height.equal(.wrap)
result.numberOfLines=1
result.textAlignment = .center
result.font = UIFont.systemFont(ofSize: TEXT_LARGE3)
result.textColor = .colorOnSurface
return result
}()
}
4)设置SuperToolbarView宽高,并将左中右布局添加到SuperToolbarView中,默认将标题添加到中间布局。
class SuperToolbarView : TGRelativeLayout{
init() {
super.init(frame: CGRect.zero)
initViews()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
initViews()
}
func initViews(){
tg_width.equal(.fill)
//系统导航栏高度是44,但看着太低了,所以增大
tg_height.equal(50)
//左侧按钮容器
addSubview(leftContainer)
//标题容器
addSubview(centerContainer)
centerContainer.addSubview(titleView)
//右侧按钮容器
addSubview(rightContainer)
}
lazy var leftContainer: TGLinearLayout = {
let r = TGLinearLayout(.horz)
r.tg_space = PADDING_MEDDLE
r.tg_gravity = TGGravity.vert.center
r.tg_leading.equal(12)
r.tg_trailing.equal(centerContainer.tg_leading).offset(PADDING_MEDDLE)
r.tg_height.equal(.fill)
return r
}()
lazy var centerContainer: TGLinearLayout = {
let r = TGLinearLayout(.horz)
r.tg_width.equal(.wrap)
r.tg_height.equal(.fill)
r.tg_gravity = TGGravity.vert.center
r.tg_centerX.equal(0)
r.tg_centerY.equal(0)
return r
}()
private lazy var rightContainer: TGLinearLayout = {
let r = TGLinearLayout(.horz)
r.tg_space = PADDING_MEDDLE
r.tg_gravity = [TGGravity.vert.center,TGGravity.horz.right]
r.tg_trailing.equal(12)
r.tg_leading.equal(centerContainer.tg_trailing).offset(PADDING_MEDDLE)
r.tg_height.equal(.fill)
return r
}()
lazy var titleView: UILabel = {
let result=UILabel()
result.tg_width.equal(SCREEN_WIDTH - 150)
result.tg_height.equal(.wrap)
result.numberOfLines=1
result.textAlignment = .center
result.font = UIFont.systemFont(ofSize: TEXT_LARGE3)
result.textColor = .colorOnSurface
return result
}()
}
5)对外暴露添加内容到左中右布局的方法。
class SuperToolbarView : TGRelativeLayout{
init() {
super.init(frame: CGRect.zero)
initViews()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
initViews()
}
func initViews(){
tg_width.equal(.fill)
//系统导航栏高度是44,但看着太低了,所以增大
tg_height.equal(50)
//左侧按钮容器
addSubview(leftContainer)
//标题容器
addSubview(centerContainer)
centerContainer.addSubview(titleView)
//右侧按钮容器
addSubview(rightContainer)
}
@discardableResult
/// 添加左侧菜单
func addLeftItem(_ data:UIView) -> SuperToolbarView {
leftContainer.addSubview(data)
return self
}
/// 中间容器添加控件
@discardableResult
func addCenterView(_ data:UIView) -> SuperToolbarView {
//隐藏标题
titleView.hide()
centerContainer.addSubview(data)
return self
}
/// 添加右侧菜单
@discardableResult
func addRightItem(_ data:UIView) -> SuperToolbarView {
rightContainer.addSubview(data)
return self
}
lazy var leftContainer: TGLinearLayout = {
let r = TGLinearLayout(.horz)
r.tg_space = PADDING_MEDDLE
r.tg_gravity = TGGravity.vert.center
r.tg_leading.equal(12)
r.tg_trailing.equal(centerContainer.tg_leading).offset(PADDING_MEDDLE)
r.tg_height.equal(.fill)
return r
}()
lazy var centerContainer: TGLinearLayout = {
let r = TGLinearLayout(.horz)
r.tg_width.equal(.wrap)
r.tg_height.equal(.fill)
r.tg_gravity = TGGravity.vert.center
r.tg_centerX.equal(0)
r.tg_centerY.equal(0)
return r
}()
private lazy var rightContainer: TGLinearLayout = {
let r = TGLinearLayout(.horz)
r.tg_space = PADDING_MEDDLE
r.tg_gravity = [TGGravity.vert.center,TGGravity.horz.right]
r.tg_trailing.equal(12)
r.tg_leading.equal(centerContainer.tg_trailing).offset(PADDING_MEDDLE)
r.tg_height.equal(.fill)
return r
}()
lazy var titleView: UILabel = {
let result=UILabel()
result.tg_width.equal(SCREEN_WIDTH - 150)
result.tg_height.equal(.wrap)
result.numberOfLines=1
result.textAlignment = .center
result.font = UIFont.systemFont(ofSize: TEXT_LARGE3)
result.textColor = .colorOnSurface
return result
}()
}
BaseTitleController
封装BaseTitleController,将SuperToolbarView添加到界面。
class BaseTitleController : BaseLogicController{
override func initLinearLayoutSafeArea() {
super.initLinearLayoutSafeArea()
prepareInitToolbar()
}
func prepareInitToolbar() {
if isAddToolBar() {
initToolbar()
}
}
func isAddToolBar() -> Bool {
return true
}
func initToolbar() {
superHeaderContentContainer.addSubview(toolbarView)
//添加返回按钮
if navigationController?.viewControllers.count != nil && navigationController?.viewControllers.count != 1 {
let r = addLeftImageButton(R.image.arrowLeft()!.withTintColor())
r.tag = VALUE10
}
}
@discardableResult
/// 添加左侧图片按钮
/// - Parameter data: <#data description#>
func addLeftImageButton(_ data:UIImage) -> QMUIButton {
let leftButton=ViewFactoryUtil.button(image: data)
leftButton.addTarget(self, action: #selector(leftClick(_:)), for: .touchUpInside)
toolbarView.addLeftItem(leftButton)
return leftButton
}
/// 添加右侧图片按钮
func addRightImageButton(_ data:UIImage) {
let rightButton = ViewFactoryUtil.button(image: data)
rightButton.addTarget(self, action: #selector(rightClick(_:)), for: .touchUpInside)
toolbarView.addRightItem(rightButton)
}
@discardableResult
/// 添加右侧按钮
/// - Parameter data: <#data description#>
func addRightButton(_ data:String) -> QMUIButton{
let rightButton = ViewFactoryUtil.linkButton()
rightButton.setTitle(data, for: .normal)
rightButton.setTitleColor(.colorOnSurface, for: .normal)
rightButton.addTarget(self, action: #selector(rightClick(_:)), for: .touchUpInside)
rightButton.sizeToFit()
toolbarView.addRightItem(rightButton)
return rightButton
}
/// 左侧按钮点击方法
/// - Parameter sender: <#sender description#>
@objc func leftClick(_ sender:QMUIButton) {
if sender.tag == VALUE10 {
navigationController?.popViewController(animated: true)
}
}
/// 右侧按钮点击方法
/// - Parameter sender: <#sender description#>
@objc func rightClick(_ sender:QMUIButton) {
}
lazy var toolbarView: SuperToolbarView = {
let r = SuperToolbarView()
return r
}()
}