Swift - 分页菜单的实现(使用PagingMenuController库实现tab标签切换)
一、安装配置


|
1
|
import PagingMenuController |
二、纯代码使用样例
1,效果图
2,样例代码
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import UIKit//子视图控制器1class ViewController1: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = UIColor.orange let textLabel = UILabel(frame: CGRect(x: 0, y: 100, width: self.view.frame.width, height: 30)) textLabel.textAlignment = .center textLabel.font = UIFont.systemFont(ofSize: 33) textLabel.textColor = .white textLabel.text = "电影" view.addSubview(textLabel) }} |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import UIKit//子视图控制器2class ViewController2: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = UIColor.darkGray let textLabel = UILabel(frame: CGRect(x: 0, y: 100, width: self.view.frame.width, height: 30)) textLabel.textAlignment = .center textLabel.font = UIFont.systemFont(ofSize: 33) textLabel.textColor = .white textLabel.text = "音乐" view.addSubview(textLabel) }} |
(3)主视图控制器(ViewController.swift)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
import UIKitimport PagingMenuController//分页菜单配置private struct PagingMenuOptions: PagingMenuControllerCustomizable { //第1个子视图控制器 private let viewController1 = ViewController1() //第2个子视图控制器 private let viewController2 = ViewController2() //组件类型 fileprivate var componentType: ComponentType { return .all(menuOptions: MenuOptions(), pagingControllers: pagingControllers) } //所有子视图控制器 fileprivate var pagingControllers: [UIViewController] { return [viewController1, viewController2] } //菜单配置项 fileprivate struct MenuOptions: MenuViewCustomizable { //菜单显示模式 var displayMode: MenuDisplayMode { return .segmentedControl } //菜单项 var itemsOptions: [MenuItemViewCustomizable] { return [MenuItem1(), MenuItem2()] } } //第1个菜单项 fileprivate struct MenuItem1: MenuItemViewCustomizable { //自定义菜单项名称 var displayMode: MenuItemDisplayMode { return .text(title: MenuItemText(text: "电影")) } } //第2个菜单项 fileprivate struct MenuItem2: MenuItemViewCustomizable { //自定义菜单项名称 var displayMode: MenuItemDisplayMode { return .text(title: MenuItemText(text: "音乐")) } }}//主视图控制器class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() //分页菜单配置 let options = PagingMenuOptions() //分页菜单控制器初始化 let pagingMenuController = PagingMenuController(options: options) //分页菜单控制器尺寸设置 pagingMenuController.view.frame.origin.y += 64 pagingMenuController.view.frame.size.height -= 64 //建立父子关系 addChildViewController(pagingMenuController) //分页菜单控制器视图添加到当前视图中 view.addSubview(pagingMenuController.view) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() }} |
源码下载:
hangge_1656.zip
三、Storyboard 使用样例
1,效果图
2,Storyboard 相关操作
(1)在主视图中添加一个 Container View,并设置好相关约束。


3,样例代码
|
1
|
//具体参考上面的纯代码实现部分 |
(2)主视图控制器(ViewController.swift)
高亮处表示与上面纯代码实现不相同的地方。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
import UIKitimport PagingMenuController//分页菜单配置private struct PagingMenuOptions: PagingMenuControllerCustomizable { //第1个子视图控制器 private let viewController1 = ViewController1() //第2个子视图控制器 private let viewController2 = ViewController2() //组件类型 fileprivate var componentType: ComponentType { return .all(menuOptions: MenuOptions(), pagingControllers: pagingControllers) } //所有子视图控制器 fileprivate var pagingControllers: [UIViewController] { return [viewController1, viewController2] } //菜单配置项 fileprivate struct MenuOptions: MenuViewCustomizable { //菜单显示模式 var displayMode: MenuDisplayMode { return .segmentedControl } //菜单项 var itemsOptions: [MenuItemViewCustomizable] { return [MenuItem1(), MenuItem2()] } } //第1个菜单项 fileprivate struct MenuItem1: MenuItemViewCustomizable { //自定义菜单项名称 var displayMode: MenuItemDisplayMode { return .text(title: MenuItemText(text: "电影")) } } //第2个菜单项 fileprivate struct MenuItem2: MenuItemViewCustomizable { //自定义菜单项名称 var displayMode: MenuItemDisplayMode { return .text(title: MenuItemText(text: "音乐")) } }}//主视图控制器class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() //获取分页菜单配置 let options = PagingMenuOptions() //设置分页菜单配置 let pagingMenuController = self.childViewControllers.first as! PagingMenuController pagingMenuController.setup(options) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() }} |
源码下载:
hangge_1656.zip
四、标签、页面切换响应
1,样例代码
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
//分页菜单控制器初始化let pagingMenuController = PagingMenuController(options: options)//....省略一些代码 view.addSubview(pagingMenuController.view)//页面切换响应pagingMenuController.onMove = { state in switch state { case let .willMoveItem(menuItemView, previousMenuItemView): print("--- 标签将要切换 ---") print("老标签:\(previousMenuItemView.titleLabel.text!)") print("新标签:\(menuItemView.titleLabel.text!)") case let .didMoveItem(menuItemView, previousMenuItemView): print("--- 标签切换完毕 ---") print("老标签:\(previousMenuItemView.titleLabel.text!)") print("新标签:\(menuItemView.titleLabel.text!)") case let .willMoveController(menuController, previousMenuController): print("--- 页面将要切换 ---") print("老页面:\(previousMenuController)") print("新页面:\(menuController)") case let .didMoveController(menuController, previousMenuController): print("--- 页面切换完毕 ---") print("老页面:\(previousMenuController)") print("新页面:\(menuController)") case .didScrollStart: print("--- 分页开始左右滑动 ---") case .didScrollEnd: print("--- 分页停止左右滑动 ---") }} |
2,运行效果
(1)我们点击顶部菜单标签进行页面切换,可以看到控制台打印出如下信息:

(2)而如果通过手指滑动切换页面,控制台打印出如下信息:

五、使用代码切换标签
|
1
|
pagingMenuController.move(toPage: 1, animated: true) |
六、自定义分页控制器样式
1,defaultPage: Int
2,animationDuration: TimeInterval
3,isScrollEnabled: Bool
4,backgroundColor: UIColor
5,lazyLoadingPage: LazyLoadingPage
|
1
2
3
4
5
|
public enum LazyLoadingPage { case one // Currently sets false to isScrollEnabled at this moment. Should be fixed in the future. case three case all // Currently not available for Infinite mode} |
6,menuControllerSet: MenuControllerSet
这个不太清楚做什么用的,也是一个枚举可选值如下:
|
1
2
3
4
|
public enum MenuControllerSet { case single case multiple} |
7,componentType: ComponentType
|
1
2
3
4
5
|
public enum ComponentType { case menuView(menuOptions: MenuViewCustomizable) case pagingController(pagingControllers: [UIViewController]) case all(menuOptions: MenuViewCustomizable, pagingControllers: [UIViewController])} |
8,下面是一个完整的配置样例
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
//分页菜单配置private struct PagingMenuOptions: PagingMenuControllerCustomizable { //默认显示第2页 var defaultPage: Int = 1 //页面切换动画播放时间为0.5秒 var animationDuration: TimeInterval = 0.5 //不允许手指左右滑动页面切换 var isScrollEnabled: Bool = false //页面背景色为紫色 var backgroundColor: UIColor = .purple //lazy loading的页面数量(默认值就是.three) var lazyLoadingPage: LazyLoadingPage = .three //不太清楚干嘛用的(默认值就是.multiple) var menuControllerSet: MenuControllerSet = .multiple //第1个子视图控制器 private let viewController1 = ViewController1() //第2个子视图控制器 private let viewController2 = ViewController2() //组件类型 fileprivate var componentType: ComponentType { return .all(menuOptions: MenuOptions(), pagingControllers: pagingControllers) } //所有子视图控制器 fileprivate var pagingControllers: [UIViewController] { return [viewController1, viewController2] } //菜单配置项 fileprivate struct MenuOptions: MenuViewCustomizable { //菜单显示模式 var displayMode: MenuDisplayMode { return .segmentedControl } //菜单项 var itemsOptions: [MenuItemViewCustomizable] { return [MenuItem1(), MenuItem2()] } } //第1个菜单项 fileprivate struct MenuItem1: MenuItemViewCustomizable { //自定义菜单项名称 var displayMode: MenuItemDisplayMode { return .text(title: MenuItemText(text: "电影")) } } //第2个菜单项 fileprivate struct MenuItem2: MenuItemViewCustomizable { //自定义菜单项名称 var displayMode: MenuItemDisplayMode { return .text(title: MenuItemText(text: "音乐")) } }} |
七、自定义菜单栏样式
1,backgroundColor: UIColor
2,selectedBackgroundColor: UIColor
3,height: CGFloat
4,animationDuration: TimeInterval
5,deceleratingRate: CGFloat
6,menuSelectedItemCenter: Bool
7,displayMode: MenuDisplayMode
|
1
2
3
4
5
6
7
|
public enum MenuDisplayMode { case standard(widthMode: MenuItemWidthMode, centerItem: Bool, scrollingMode: MenuScrollingMode) case segmentedControl case infinite(widthMode: MenuItemWidthMode, scrollingMode: MenuScrollingMode) //这个至少要求有3个页面} |
其中的 MenuItemWidthMode、MenuScrollingMode 也是枚举:
|
1
2
3
4
5
6
7
8
9
10
11
12
|
//设置菜单标签的宽度public enum MenuItemWidthMode { case flexible //自动 case fixed(width: CGFloat) //固定宽度}//菜单如何滚动public enum MenuScrollingMode { case scrollEnabled //可以跨多个菜单项切换 case scrollEnabledAndBouces //可以跨多个菜单项切换 case pagingEnabled //菜单只能一个接一个切换} |
- 样例1:分段模式

|
1
2
3
4
|
//菜单显示模式(分段模式)var displayMode: MenuDisplayMode { return .segmentedControl} |
- 样例2:标准模式,这里我让选中标签始终居中
|
1
2
3
4
5
|
//菜单显示模式(标准模式)var displayMode: MenuDisplayMode { return .standard(widthMode: .fixed(width: 30), centerItem: true, scrollingMode: .pagingEnabled)} |
- 样例3:无限循环模式(这个必需至少有三个菜单项)
|
1
2
3
4
|
//菜单显示模式(无限循环模式)var displayMode: MenuDisplayMode { return .infinite(widthMode: .flexible, scrollingMode: .pagingEnabled)} |
8,focusMode: MenuFocusMode
选中菜单标签的样式,这个也是枚举:
|
1
2
3
4
5
6
7
|
public enum MenuFocusMode { case none case underline(height: CGFloat, color: UIColor, horizontalPadding: CGFloat, verticalPadding: CGFloat) case roundRect(radius: CGFloat, horizontalPadding: CGFloat, verticalPadding: CGFloat, selectedColor: UIColor)} |
- 样例1:无样式

|
1
2
|
//选中项无样式var focusMode: MenuFocusMode = .none |
- 样例2:下划线样式

|
1
2
3
|
//选中项为橙色下划线样式var focusMode: MenuFocusMode = .underline(height: 3, color: .orange, horizontalPadding: 0, verticalPadding: 0) |
- 样例3:圆角矩形背景样式

|
1
2
3
|
//选中项为橙色矩形背景var focusMode: MenuFocusMode = .roundRect(radius: 6, horizontalPadding: 5, verticalPadding: 8, selectedColor: .orange) |
9,dummyItemViewsSet: Int
不太清楚干嘛用的。
10,menuPosition: MenuPosition
菜单栏的位置,我们可以指定菜单栏在页面视图的上方还是下方。

|
1
2
3
4
|
public enum MenuPosition { case top case bottom} |
11,dividerImage: UIImage?
菜单标签间的分隔图片,显示在每个标签的右侧。

|
1
2
|
//设置标签间的分隔图片var dividerImage: UIImage? = UIImage(named: "dividerImage.png")! |
12,下面是完整的使用样例
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
//菜单栏配置fileprivate struct MenuOptions: MenuViewCustomizable { //设置未选中的菜单标签背景为深灰色 var backgroundColor: UIColor = .darkGray //设置选中的菜单标签背景为浅浅灰色 var selectedBackgroundColor: UIColor = .lightText //设置菜单标签高度为40 var height: CGFloat = 40 //菜单切换动画播放时间为0.5秒 var animationDuration: TimeInterval = 0.5 //菜单切换动画减速率(默认为:UIScrollViewDecelerationRateFast) var deceleratingRate: CGFloat = UIScrollViewDecelerationRateFast //不知道干嘛的 var menuSelectedItemCenter: Bool = false //菜单显示模式(分段模式) var displayMode: MenuDisplayMode { return .segmentedControl } //选中项为橙色矩形背景 var focusMode: MenuFocusMode = .roundRect(radius: 6, horizontalPadding: 5, verticalPadding: 8, selectedColor: .orange) //不知道干嘛的 var dummyItemViewsSet: Int = 3 //设置菜单栏在下方 var menuPosition: MenuPosition = .bottom //设置标签间的分隔图片 var dividerImage: UIImage? = UIImage(named: "dividerImage.png")! //菜单项 var itemsOptions: [MenuItemViewCustomizable] { return [MenuItem1(), MenuItem2(), MenuItem3() , MenuItem4()] }} |
八、自定义单独的菜单标签样式
MenuItemViewCustomizable 对象有如下几个属性可以对单独的菜单项进行自定义:
1,horizontalMargin: CGFloat

|
1
2
3
4
5
6
7
8
|
//第2个菜单项fileprivate struct MenuItem2: MenuItemViewCustomizable { //该标签的水平边距设为50 var horizontalMargin: CGFloat = 50 //自定义菜单项名称 var displayMode: MenuItemDisplayMode = .text(title: MenuItemText(text: "音乐e"))} |
2,displayMode: MenuItemDisplayMode
|
1
2
3
4
5
6
|
public enum MenuItemDisplayMode { case text(title: MenuItemText) //普通标题文本 case multilineText(title: MenuItemText, description: MenuItemText) //标题+描述文本 case image(image: UIImage, selectedImage: UIImage?) //图片 case custom(view: UIView) //自定义视图} |
- 样例1:标签显示为标题+描述文本

|
1
2
3
4
5
6
7
8
9
10
11
12
|
//第2个菜单项fileprivate struct MenuItem2: MenuItemViewCustomizable { //该标签的水平边距设为50 var horizontalMargin: CGFloat = 50 //自定义菜单项标题和描述 var displayMode: MenuItemDisplayMode { let desFont = UIFont.systemFont(ofSize: 10) let description = MenuItemText(text: "Music", font: desFont , selectedFont: desFont ) return .multilineText(title: MenuItemText(text: "音乐"), description: description) }} |
- 样例2:将菜单标签显示为图片

|
1
2
3
4
5
6
7
8
9
10
11
|
//第2个菜单项fileprivate struct MenuItem2: MenuItemViewCustomizable { //该标签的水平边距设为50 var horizontalMargin: CGFloat = 50 //菜单项显示为图片 var displayMode: MenuItemDisplayMode { return .image(image: UIImage(named: "forward")!, selectedImage: UIImage(named: "forward")!) }} |
原文出自:www.hangge.com 转载请保留原文链接:http://www.hangge.com/blog/cache/detail_1656.html
Swift - 分页菜单的实现(使用PagingMenuController库实现tab标签切换)的更多相关文章
- swift调用oc语言文件,第三方库文件或者自己创建的oc文件——简书作者
Swift是怎样调用OC的第三方库的呢?请看下面详情: 情况一: 1.首先打开Xcode,iOS->Application->Single View Application, 选Next. ...
- 微信小程序组件 分页菜单点击请求
//JS data: { navNum:0, navList: [ { id: 1, name: '已预约' }, { id: 2, name: '已消费' }, { id: 3, name: '已取 ...
- [Swift通天遁地]九、拔剑吧-(5)创建Tab图标具有多种样式的Tab动画
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- [Swift通天遁地]九、拔剑吧-(8)创建气泡式页面切换效果
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- JSTL标签库之核心标签
一.JSTL标签库介绍 JSTL标签库的使用是为弥补html标签的不足,规范自定义标签的使用而诞生的.使用JSLT标签的目的就是不希望在jsp页面中出现java逻辑代码 二.JSTL标签库的分类 核心 ...
- 【液晶模块系列基础视频】4.4.X-GUI图形界面库-画tab函数简介
[液晶模块系列基础视频]4.4.X-GUI图形界面库-画tab函数简介 ============================== 技术论坛:http://www.eeschool.org 博客地址 ...
- javaweb学习总结(二十八)——JSTL标签库之核心标签
一.JSTL标签库介绍 JSTL标签库的使用是为弥补html标签的不足,规范自定义标签的使用而诞生的.使用JSLT标签的目的就是不希望在jsp页面中出现java逻辑代码 二.JSTL标签库的分类 核心 ...
- 学会怎样使用Jsp 内置标签、jstl标签库及自定义标签
学习jsp不得不学习jsp标签,一般来说,对于一个jsp开发者,可以理解为jsp页面中出现的java代码越少,对jsp的掌握就越好,而替换掉java代码的重要方式就是使用jsp标签. jsp标签的分 ...
- javaWeb学习总结(9)- JSTL标签库之核心标签
一.JSTL标签库介绍 JSTL标签库的使用是为弥补html标签的不足,规范自定义标签的使用而诞生的.使用JSLT标签的目的就是不希望在jsp页面中出现java逻辑代码 二.JSTL标签库的分类 核心 ...
随机推荐
- POJ 2337 欧拉回路
题意: 如果给出的单词能够首尾相接,请按字典序输出单词,中间要加'.' 否则输出三个"*". 思路: 欧拉回路 记得按字典序排序哦~ 加边的时候要倒着加.(邻接表遍历的时候是反着的 ...
- B - Even Odds
Problem description Being a nonconformist, Volodya is displeased with the current state of things, p ...
- Linux od与hexdump命令
od命令:以指定格式输出文件内容常用格式:od -Ax -tx1 filename直接格式:od filename 等价 od -o filename语法:od [-abcdfsiloxv] [-An ...
- 修改织梦plus目录名
1.修改plus目录名 修改inlclude文件夹下common.inc.php 140行 //插件目录,这个目录是用于存放计数器.投票.评论等程序的必要动态程序 $cfg_plus_dir = $c ...
- 在无任何报错的情况下 pagehelper.startpage分页无效问题
问题原因:自从spring boot开始使用2.0x版本以上后,很多相应的依赖文件版本开始变化 该版本为spring-boot 1.4.1 <dependency> <groupId ...
- SIFT算法总结:用于图像搜索
原始文章链接:http://bubblexc.com/y2011/163/ 原文链接:http://blog.csdn.net/cserchen/article/details/5606859 关于三 ...
- 杭电 1013 Digital Roots
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1013 反思:思路很简单,但是注意各位数加起来等于10的情况以及输入0的时候结束程序该怎么去表达 #in ...
- 2017/01/20 学习笔记 关于修改和重打jar包
背景 客户提供了jar包,但发现db表中缺少一个字段,db追加以后需要修改jar包中的source. 操作 如何修改jar包中的source并重新打一个新的jar包,做了如下操作. ① 开包 解压j ...
- 01--[转]C++强大背后
[转]C++强大背后 2014-01-22 分类:互联网 阅读(9295) 评论(6) 在31年前(1979年),一名刚获得博士学位的研究员,为了开发一个软件项目发明了一门新编程语言,该研究员名为Bj ...
- (转)基于MVC4+EasyUI的Web开发框架形成之旅--框架总体界面介绍
http://www.cnblogs.com/wuhuacong/p/3344096.html 在前面介绍了一些关于最新基于MVC4+EasyUI的Web开发框架文章,虽然Web开发框架的相关技术文章 ...