IOS 22 自定义标题栏(Toolbar)

news2024/9/21 18:56:35

标题栏实现效果

实现逻辑

自定义标题栏,我们可以基于系统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
    }()
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2106246.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何查找自己文件的复制记录 - 用这个方法简单

如何查看自己文件的复制记录&#xff1f;在电脑操作的过程中经常会复制文件&#xff0c;那么这些记录在哪里可以看&#xff0c;怎么查找&#xff0c;我们可以使用专门的软件工具进行查看文件的复制、剪切历史记录&#xff0c;下面推荐一款比较实用的文件复制记录查看软件。 文…

Chrome 浏览器插件获取网页 window 对象(方案三)

前言 最近有个需求&#xff0c;是在浏览器插件中获取 window 对象下的某个数据&#xff0c;当时觉得很简单&#xff0c;和 document 一样&#xff0c;直接通过嵌入 content_scripts 直接获取&#xff0c;然后使用 sendMessage 发送数据到插件就行了&#xff0c;结果发现不是这…

51单片机-第十一节-DS18B20温度传感器(One_Wire单总线)

一、DS18B20温度传感器介绍&#xff1a; DS18B20是一种数字温度传感器。 测温范围&#xff1a;-55C - 125C 通信接口&#xff1a;1-Wire&#xff08;单总线&#xff09; 二、引脚及应用电路&#xff1a; 很简单&#xff0c;电源&#xff0c;接地&#xff0c;通讯接口。 三…

认知杂谈38

今天分享 有人说的一段争议性的话 I I 《灵感&#xff0c;创意的魔法棒》 嘿&#xff0c;咱可得好好唠唠灵感这玩意儿。你说怪不怪&#xff0c;有时候就喝那么一杯热乎乎的茶&#xff0c;哎呀妈呀&#xff0c;脑袋里一下子就跟开了闸似的&#xff0c;各种点子“哗哗”地往外…

[米联客-XILINX-H3_CZ08_7100] FPGA程序设计基础实验连载-29基于FPGA实现触摸屏实验

软件版本&#xff1a;VIVADO2021.1 操作系统&#xff1a;WIN10 64bit 硬件平台&#xff1a;适用 XILINX A7/K7/Z7/ZU/KU 系列 FPGA 实验平台&#xff1a;米联客-MLK-H3-CZ08-7100开发板 板卡获取平台&#xff1a;https://milianke.tmall.com/ 登录“米联客”FPGA社区 http…

FFmpeg开发笔记(五十四)使用EasyPusher实现移动端的RTSP直播

之前的文章《利用RTMP协议构建电脑与手机的直播Demo》介绍了如何使用RTMP Streamer实现完整的RTMP直播流程&#xff0c;另一篇文章《利用SRT协议构建手机APP的直播Demo》介绍了如何使用SRT Streamer实现完整的SRT直播流程&#xff0c;接下来介绍如何使用EasyPusher-Android实现…

golang学习笔记03——gin框架的核心数据结构

文章目录 1.核心数据结构1.1 gin.Context1.2 前缀树&#xff08;1&#xff09;前缀树&#xff08;2&#xff09;压缩前缀树&#xff08;3&#xff09;代码实现 上期文章我们讲到了golang中gin框架的基本原理和底层请求、渲染的流程&#xff0c;还不知道的小伙伴查看golang学习笔…

Docker 部署 Redis (图文并茂超详细)

部署 Redis ( Docker ) [Step 1] : 拉取 Redis 镜像, 推荐使用 7 的 Redis 版本 docker pull redis:7.0.12[Step 2] : 创建 Redis 相关目录 ➡️ 启动 Redis 容器 ➡️ 拷贝文件 ➡️ 授权文件夹 ➡️ 删除容器 # 创建 Redis 相关目录 mkdir -p /data/redis/{conf,data,log…

页面小组件-搜索栏(一)

样例展示 效果示例-折叠状态 效果示例-展开状态 代码示例 <custom-search-wrapper><!--showFoldBtn 需要展示折叠按钮时传值--><template slotleft><el-form:model"searchFormData"inlinesize"small"><el-form-item><e…

Linux 虚拟网络三大基石:Namespace、Veth pair 与 Bridge

引言 在 Linux 的世界里&#xff0c;虚拟网络技术是系统管理、云计算和容器化不可或缺的一部分。今天&#xff0c;我们将深入探讨构建这些虚拟网络的三大基石&#xff1a;Namespace、Veth 对和 Bridge&#xff0c;揭示它们如何在背后默默支撑起你的网络环境。 Namespace&…

PNP与NPN型传感器

PNP与NPN型传感器 一、磁性开关1、==磁性开关分类及原理==:2、==磁性开关配线==3、磁性开关串连和并联(不重要)4、磁性开关选型(不重要)二、PNP型与NPN型的选用1、PNP型传感器(高电平输出)1.1、对于`PNP-NO`(常开)型1.2、对于`PNP-NC`(常闭)型:2、NPN型传感器(低电…

Navicat 17 新特性 | 新增 Redis 哨兵部署模式

随着 Navicat 17 的发布&#xff0c;在业界引起了广泛的共鸣与热议。我们曾深入剖析其众多革新特性&#xff0c;包括新增 PolarDB 与 Garnet、模型设计创新与优化、增强的商业智能 BI 能力、高效的查询与配置、用户界面交互体验再升级&#xff0c;以及原生适配国产平台和操作系…

商品信息的标准化

销售环节的数字化见效最快 现在&#xff0c;企业的数字化是非常热的话题&#xff0c;工业&#xff14;.&#xff10;&#xff0c;人工智能&#xff0c;物联网&#xff0c;机器人都是企业数字化转型的主要方向&#xff0c;但是某些时候&#xff0c;我们走的太远&#xff0c;却忘…

双向链表的学习

双向链表是一种数据结构&#xff0c;它由节点组成&#xff0c;每个节点包含两个指针&#xff1a;一个指向前一个节点&#xff0c;另一个指向后一个节点。这种结构允许数据元素在两个方向上进行遍历&#xff0c;即既可以从前到后&#xff08;顺序&#xff09;&#xff0c;也可以…

【微处理器系统原理和应用设计第六讲】片上微处理器系统系统架构

一、概念辨析 首先来厘清以下概念&#xff1a;微处理器&#xff0c;微控制器&#xff0c;单片机&#xff0c;片上微处理器系统 &#xff08;1&#xff09;微处理器&#xff1a;即MPU&#xff08;Microprocessor Unit&#xff09;&#xff0c;微处理器是一种计算机的中央处理单…

Vue封装的过度与动画(transition-group、animate.css)

目录 1. Vue封装的过度与动画1.1 动画效果11.2 动态效果21.3 使用第三方动画库animate.css 1. Vue封装的过度与动画 作用&#xff1a;在插入、更新或移除DOM元素时&#xff0c;在合适的时候给元素添加样式类名 1.1 动画效果1 Test1.vue: transition内部只能包含一个子标签。…

电脑知识:如何恢复 Word、媒体和存档文件?

如果您是 Word 用户&#xff0c;那么您一定对无法打开 Word 文档的问题很熟悉。当文档包含大量关键信息时&#xff0c;情况会变得更加复杂。如果您遇到这种情况&#xff0c;那么您将如何处理&#xff1f; 我们再怎么强调在外部存储位置&#xff08;如外部硬盘、网络位置&#…

Ubuntu设置

1.查看版本:lsb_release -a 2.配置相关参数 配置root用户 设置 root 用户的登录密码&#xff0c;然后 su 登录。 1.改root密码&#xff1a;sudo passwd root 2.切换登录root用户&#xff1a; su root 3.root主目录在&#xff1a;cd ~ 4.开启 root 用户SSH远程登录权限 …

学习记录——day43 C++ 异常处理

一、异常处理的格式 1、在可能产生异常的地方使用关键字&#xff1a;throw 抛出异常 2、try { 可能会抛出异常的语句 }catch(接收异常的形参) { 处理异常 } 任何函数在定义时&#xff0c;可以指定能抛出的异常格式如下 返回值类型 函数…

前端:HTML、CSS、JS、Vue

1 前端 内容概要 了解前端三件套(HTML、CSS、JS)在前端所起的作用掌握HTML标签的功能&#xff0c;掌握重要标签(a标签&#xff0c;form标签)了解CSS了解JS的基础语法掌握Vue的基础语法重点掌握Vue项目怎么启动项目掌握前后端分离是什么。前端做什么事情&#xff0c;后端做什么…