Swift封装 滑出式导航栏

前言: 本文将会创建以下几个主类:

DWContainerViewController:这包含了左视图,中视图和右视图控制器的视图,并处理动画和滑动等操作。 DWCenterViewController:中央面板。 DWSidePanelViewController:用于左侧和右侧面板。

创建storyboard,如图:

并且创建DWCenterViewControllerDWStarCellDWSidePanelViewController,关联上图中的storyboard

DWCenterViewController为滑出式导航的类,代码:

class DWCenterViewController: UIViewController {var delegate: DWCenterViewControllerDelegate?@IBOutlet weak var imageView: UIImageView!@IBOutlet weak var titleLabel: UILabel!@IBOutlet weak var creatorLabel: UILabel!@IBAction func actorsTapped(_ sender: Any) {//左边点击事件   }
}
复制代码

DWStarCell代码:

class DWStarCell: UITableViewCell {@IBOutlet weak var animalImageView: UIView!@IBOutlet weak var imageNameLabel: UILabel!@IBOutlet weak var imageCreatorLabel: UILabel!}
复制代码

创建DWStar.swift模型,并且初始化cell显示的数据,代码如下:

//结构体
struct DWStar {let title: Stringlet creator: Stringlet image: UIImage?//重写init方法init(title: String, creator: String, image:UIImage?) {self.title = titleself.creator = creatorself.image = image}static func allActors() -> [DWStar] {return [DWStar(title: "林志玲", creator: "Dwyane", image: UIImage(named: "ID-100113060")),DWStar(title: "张歆艺", creator: "Dwyane", image: UIImage(named: "ID-10022760")),DWStar(title: "李连杰", creator: "Dwyane", image: UIImage(named: "ID-10091065")),DWStar(title: "周润发", creator: "Dwyane", image: UIImage(named: "ID-10047796")),DWStar(title: "舒淇", creator: "Dwyane", image: UIImage(named: "ID-10092572")),DWStar(title: "鹿晗", creator: "Dwyane", image: UIImage(named: "ID-10041194")),DWStar(title: "黄晓明", creator: "Dwyane", image: UIImage(named: "ID-10017782")),DWStar(title: "李赛凤", creator: "Dwyane", image: UIImage(named: "ID-10091745")),DWStar(title: "赵丽颖", creator: "Dwyane Ratcliff", image: UIImage(named: "ID-10056941")),DWStar(title: "周星驰", creator: "Dwyane", image: UIImage(named: "ID-10019208")),DWStar(title: "杜海涛", creator: "Dwyane", image: UIImage(named: "ID-10011404"))]}复制代码

创建DWCenterViewControllerDelegate,并且创建协议方法:

//创建协议 optional:类似oc的可选
@objc
protocol DWCenterViewControllerDelegate {@objc optional func toggleLeftPanel()  //切换左边的容器@objc optional func collapseSidePanels() //折叠侧边的容器
}
复制代码

DWCenterViewController.swiftactorsTapped点击方法调用协议方法toggleLeftPanel,如下:

@IBAction func actorsTapped(_ sender: Any) {//左边点击事件delegate?.toggleLeftPanel?()
}
复制代码

创建DWSidePanelViewControllerDelegate.swift,并创一个协议

protocol DWSidePanelViewControllerDelegate {func didSelectAnimal(_ animal: DWStar)  //选择的动物
}
复制代码

DWCenterViewController.swift实现DWSidePanelViewControllerDelegate的协议方法:

// MARK: - DWCenterViewController delegate
//在该类实现delegate的方法
extension DWCenterViewController: DWSidePanelViewControllerDelegate {func didSelectAnimal(_ animal: DWStar) { //实现协议方法imageView.image = animal.imagetitleLabel.text = animal.titlecreatorLabel.text = animal.creatordelegate?.collapseSidePanels?() //折叠侧容器}  
}
复制代码

创建DWContainerViewController.swift,并定义一些属性:

//枚举  滑动状态
enum SlideOutState {case bothCollapsed  //侧容器折叠case leftPanelExpanded   //左容器展开case rightPanelExpanded  //右容器展开
}//定义属性
var centerNavigationController: UINavigationController!
var centerViewController: DWCenterViewController!
//当前状态
var currentState: SlideOutState = .bothCollapsed {didSet { //在属性值改变后触发didSetlet shoulShowShadow = currentState != .bothCollapsed}
}var leftViewController: DWSidePanelViewController?
var centerPanelExpandedOffset: CGFloat = 60 //该值是中央视图控制器在屏幕外动画显示后左侧可见的宽度(以点为单位)
复制代码

扩展UIStoryboard,方便取得VC,代码如下:

private extension UIStoryboard {static func mainStoryboard() -> UIStoryboard {return UIStoryboard(name: "Main", bundle: Bundle.main)}static func centerViewController() -> DWCenterViewController? {return mainStoryboard().instantiateViewController(withIdentifier: "DWCenterViewController") as? DWCenterViewController}static func leftViewController() -> DWSidePanelViewController? {return mainStoryboard().instantiateViewController(withIdentifier: "LeftViewController") as? DWSidePanelViewController}    
}
复制代码

viewDidLoad添加如下:

//添加中间控制器并显示
centerViewController = UIStoryboard.centerViewController()
centerViewController.delegate = self//将centerViewController包装在导航控制器中
centerNavigationController = UINavigationController(rootViewController: centerViewController)
//加入centerViewcontroller的视图
view.addSubview(centerNavigationController.view)
//加入centerViewcontroller的视图控制器
addChildViewController(centerNavigationController)
centerNavigationController.didMove(toParentViewController: self)
复制代码

实现协议方法(添加左侧容器一起动画的发生代码):

extension DWContainerViewController: DWCenterViewControllerDelegate { 
}
复制代码

在协议方法中,添加

func toggleLeftPanel() {//如果当前状态:左边为展开let notAlreadyExpanded = (currentState != .leftPanelExpanded)if notAlreadyExpanded {addLeftPanelViewController() //添加左边容器}//左边容器展开的动画animateLeftPanel(shouldExpand: notAlreadyExpanded)
}//折叠侧边容器
func collapseSidePanels() {switch currentState {case .leftPanelExpanded:toggleLeftPanel()default:break}
}//左边的VC
func addLeftPanelViewController() {//guard语句判断其后的表达式布尔值为false时,才会执行之后代码块里的代码,如果为true,则跳过整个guard语句guard leftViewController == nil else { return }if let vc = UIStoryboard.leftViewController() {vc.animals = DWStar.allActors()addChildSidePanelController(vc)leftViewController = vc}
}func addChildSidePanelController(_ sidePanelController: DWSidePanelViewController) {sidePanelController.delegate = centerViewControllerview.insertSubview(sidePanelController.view, at: 0)addChildViewController(sidePanelController)sidePanelController.didMove(toParentViewController: self)
}//右边的VC
func addRightPanelViewController() {}func animateLeftPanel(shouldExpand: Bool) {if shouldExpand {currentState = .leftPanelExpandedanimateCenterPanelXPosition(targetPosition: centerNavigationController.view.frame.width - centerPanelExpandedOffset)} else {animateCenterPanelXPosition(targetPosition: 0, completion: { (_) inself.currentState = .bothCollapsedself.leftViewController?.view.removeFromSuperview()self.leftViewController = nil})}
}//检查是否被告知展开或折叠侧面板。如果它应该展开,那么它将设置当前状态以指示左侧面板展开,然后为中央面板设置动画,以便打开。否则,它将关闭中央面板,然后移除其视图,并设置当前状态以指示其关闭。
func animateCenterPanelXPosition(targetPosition: CGFloat, completion: ((Bool) -> Void)? = nil) {UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: .curveEaseOut, animations: {self.centerNavigationController.view.frame.origin.x = targetPosition}, completion: completion)
}func showShadowForCenterViewController(_ shouldShowShadow: Bool) {if shouldShowShadow {centerNavigationController.view.layer.shadowOpacity = 0.8} else {centerNavigationController.view.layer.shadowOpacity = 0.0}
}}
复制代码

添加手势,更改DWCenterViewController的导航栏x坐标

// 手势
// MARK: Gesture recognizer
extension DWContainerViewController: UIGestureRecognizerDelegate {@objc func handlePanGesture(_ recognize: UIPanGestureRecognizer) {let gestureIsDraggingFromLeftToRight = (recognize.velocity(in: view).x > 0)switch recognize.state {case .began:if currentState == .bothCollapsed {if gestureIsDraggingFromLeftToRight {//左边addLeftPanelViewController()} else {//右边addRightPanelViewController()}showShadowForCenterViewController(true)}case .changed:if let rview = recognize.view {rview.center.x = rview.center.x + recognize.translation(in: view).xrecognize.setTranslation(CGPoint.zero, in: view)//translationInView:方法获取View的偏移量  setTranslation:方法设置手势的偏移量}case .ended: //根据不同的方向移动左或右if let _ = leftViewController,let rview = recognize.view {let hasMovedGreaterThanHalfway = rview.center.x > view.bounds.size.widthanimateLeftPanel(shouldExpand: hasMovedGreaterThanHalfway)}default:break}}
}
复制代码

代码传送门 注意:

1、自己添加tableView,需要手动添加dataSource 和 delegate 2、调节tableView的row height

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

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

相关文章

广东电网计算机专业笔试题目,广东电网笔试题目

广东电网笔试题目笔试是一种与面试对应的测试,是以填写的方法考核应聘者学识水平的重要工具。这种方法可以有效的测量应聘人的基本知识、专业知识、管理知识、综合分析能力和文字表达能力等素质及能力的差异。下面是小编为大家收集的广东电网笔试题目,希…

波特率和比特率

波特率(符号率),可以理解为传输介质实际能达到的电压变化,比如每秒可以改变多少次。 比特率,是逻辑层面上每秒能传输多少个比特。 考虑最简单的不归零编码,用5伏电压表示1,-5伏电压表示0&…

usart和uart 的区别

摘自:https://blog.csdn.net/meic51/article/details/7714847 什么是同步和异步 转自https://blog.csdn.net/seashine_yan/article/details/71192283转载于:https://www.cnblogs.com/chulin/p/8661720.html

苹果产品开发的绝密工作流程

长期以来苹果产品开发流程在很多方面都笼罩着一层神秘的面纱,而在AdamLashinsky新发行的《InsideApple:HowAmerica’sMostAdmired–andSecretive–CompanyReallyWorks》一书中对这些流程有所涉及。这本书同时谈论了苹果公司各个不同的方面,包括其理念、招…

Linux系统集群架构线上项目配置实战(一)

项目整体介绍 **整个项目包括以下几个应用工程** 1、 用户APP 2、 商家APP 3、 业务平台管理后台 4、 商家业务管理后台 5、 官网 **整体项目规划设计如下** 1、 用户APP采用JAVA环境布署,初始环境两台服务器,实现负载均衡与高可用,前端…

如何确定autosar的版本_AUTOSAR编码指南(中文版)

在汽车应用领域,软件开发变得越来越重要。随着安全、环境以及便利性需求的增长,车辆中应用电子系统的数量也在急速增长。其中有90%的创新应用都是基于软件驱动的电子组件。而这些组件的研发成本占车辆开发成本的40%,快速稳定的发展需要整合更…

3个月计算机考研,【图片】(重开)三个月考研成功的心路历程 -南邮计算机【南京邮电大学研究生院吧】_百度贴吧...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼这个帖子教你如何在较短时间拿到大部分的分值。声明:这个经验是我个人的经历可能对有些人不适合 时间充裕的还是老老实实打基础,按部就班的三轮复习。18年考研 南邮 初试数据结构 复试微机原理 。我是国庆之…

PS把一张白色背景的图片设为透明

方法一: 1.双击图层缩略图上的小锁图标(注意,这里不要拖动小锁进行删除锁定),弹出“新建图层”,确定 2.右键左侧第四个功能菜单,选择魔棒工具 3.用魔棒工具在白色背景区域点击一下,选…

HTML5 webfont字体图标的使用

2019独角兽企业重金招聘Python工程师标准>>> 一.参考文献 1.http://www.cnblogs.com/yes-V-can/p/5716853.html 2.http://blog.csdn.net/zhouwangling_/article/details/53096649 二.html使用方法 1.下载字体 网上百度自己要使用的字体,一般下载的是ttf格…

算法导论中英文版下载

算法导论: 学过计算机的都知道,这本书可以说是全世界最权威的算法课程的大学课本了,基本上全世界的名牌大学用的教材都是它。这本书一共四位作者,Thomas H. Cormen,Charles E. Leiserson 和 Ronald L.Rivest 是来自 MI…

javaweb不同用户需要几张表_程序员必备2020版:JavaWeb快速进阶全套教程

Java Web应用由一组Servlet、HTML页、类、以及其它可以被绑定的资源构成。它可以在各种供应商提供的实现Servlet规范的Servlet容器中运行。JavaWeb项目简单来说就是一个应用程序,比如每天打开的QQ、微信、百度地图等,这些都是应用程序。有很多同学反应Ja…

遇见未来的自己作文800计算机,遇见未来的自己作文800字

如果给你一个机会让你遇见未来的自己,并且有两个不一样的人生,任意选择其中一个,你愿意去遇见吗?在我的面前,有两扇门。可以看见其中一扇门上写着“少时享受的未来,而另一扇门上写着“少时勤奋的未来”。这…

ZOJ.3551.Bloodsucker(期望DP)

题目链接 \(Description\) 有1个吸血鬼和n-1个人,每天有且只会有两个人/吸血鬼相遇,如果是人与吸血鬼相遇,那个人会有p的概率变成吸血鬼;否则什么也不发生。求n个都变成吸血鬼的期望天数。 \(Solution\) 我还是写一下吧。。期望题…

Git 回滚动任意版本

为什么80%的码农都做不了架构师?>>> Git经常会碰到版本回滚的问题,下面就介绍一下如何回滚版本。 显示提交的log $ git log commit 38be40e4cbdb5512c8318c5ab4e09c462ff5095a (HEAD -> dev, origin/master, origin/dev, origin/HEAD, ma…

axureux中后台管理信息系统通用原型方案 v2_前端公共图表数据大盘方案

作者 | 马一文程序员中的一种,偶尔吟湿作对,润滑万物 ——子慕大诗人前言前端常常会在的业务中后台开发数据统计图表,对于类似 Echarts 这种配置性极强的库,需要花费很多时间查看文档, 一个项目中统计图表大多情况下只…

从程序员到技术总监,分享10年开发经验

在中国有很多人都认为IT行为是吃青春饭的,如果过了30岁就很难有机会再发展下去!其实现实并不是这样子的,在下从事.NET及JAVA方面的开发的也有10年的时间了,在这里在下想凭借自己的亲身经历,与大家一起探讨一下。 明确入…

计算机风险评估管理程序,第5章 信息安全风险评估实施流程

《第5章 信息安全风险评估实施流程》由会员分享,可在线阅读,更多相关《第5章 信息安全风险评估实施流程(25页珍藏版)》请在人人文库网上搜索。1、第第5章章 信息安全风险信息安全风险评估评估 实施实施流程流程 赵赵 刚刚 信 息 安 全 管 理 与 风 险 评…

机器学习:算法模型:决策树

原文链接:https://www.cnblogs.com/wenyi1992/p/7685131.html 【基本流程】 分类决策树的核心思想就是在一个数据集中找到一个最优特征,然后从这个特征的选值中找一个最优候选值(这段话稍后解释),根据这个最优候选值将数据集分为两个子数据集…