分段控制器UISegmentedControl的使用、同一个控制器中实现多个View的切换、addChildViewController等方法的使用
本文先讲解简单的分段控制器UISegmentedControl的使用,然后具体讲解它最常使用的场景:同一个控制器中实现多个View的切换。
文章构思:
1、先直接讲解一张UI效果图的四种实现方式。
2、对UISegmentedControl类的各种属性和各种方法的讲解。
UISegmentedControl控件的很大的使用场景基本像下面这张图显示的一样,在同一个控制器中实现多个View的切换。

结合这张图,我先讲解下产品的要求。导航栏上面放置一个UISegmentedControl控件,可以切换“空间”数据、“活动”数据。并且空间数据的展示界面和活动数据的展示界面是不一样的UI布局。
当然,如果这多个界面的UI布局是一样的,不同的只是数据,那肯定就采用同一个控制器、同UI界面,赋予不同的数据,然后刷新就好了。
为了实现这样的效果,一般市面上有四种实现方案,我比较偏向使用第三种。第四种也就是将前面两种方法结合起来使用。

第一种方式:如上图所示,实现的思路就是使用UIScrollView控件,将ViewA和ViewB都放置在UIScrollView中,然后当点击UISegmentedControl控件时,使用UIScrollView对象的内容偏移的方式,达到所需效果。
好处:两个View是放置在ScrollView上面的,View切换过程中,比较顺畅、可以同时存在ViewA的右半部分、ViewB的左半部分。
坏处:ViewA和ViewB都是由VCA这样一个控制器控制的。包括ViewA和ViewB上面数据的请求、数据的处理、界面交互的处理等等事宜,都是由VCA控制器来处理。这样的话,势必造成VCA代码比较混乱,不方便管理。

第二种方式:如上图所示,让ViewA有自己的控制器VCA、ViewB也有自己的控制器VCB,让ViewB放置在ViewA上面就行了。只是在这个过程中,不能简单的只调用addSubView:方法,还有使用addChildViewController:方法。
苹果官方的解释:
苹果新的API增加了addChildViewController方法,并且希望我们在使用addSubview时,同时调用[self addChildViewController:child]方法将subview对应的viewController也加到当前ViewController的管理中。
对于那些当前暂时不需要显示的subview,只通过addChildViewController把subViewController加进去;需要显示时再调用transitionFromViewController方法。将其添加进入底层的ViewController中。
这样做的好处:
1.无疑,对页面中的逻辑更加分明了。相应的View对应相应的ViewController。
2.当某个子View没有显示时,将不会被Load,减少了内存的使用。
3.当内存紧张时,没有Load的View将被首先释放,优化了程序的内存释放机制。
然后这里就涉及到addChildViewController等方法的使用,网上对它的介绍内容比较繁多,总结起来其实也就是下面这个代码,使用的时候照搬即可:
if (添加controller控制器) {
[self addChildViewController:controller];
[controller didMoveToParentViewController:self];
} else {// 删除controller控制器
[controller willMoveToParentViewController:nil];
[controller removeFromParentViewController];
}
现在直接给出,完成项目要求的相关代码:(不能直接使用,主要是看方法)
@property (nonatomic, strong) UISegmentedControl *segmentedControl;
@property (nonatomic, strong) WSFShopActivityListVC *shopActivityListVC; - (UISegmentedControl *)segmentedControl {
if (!_segmentedControl) {
_segmentedControl = [[UISegmentedControl alloc] initWithItems:@[@"空间",@"活动"]];
_segmentedControl.frame = CGRectMake(, , , );
_segmentedControl.selectedSegmentIndex = ;
_segmentedControl.tintColor = [UIColor whiteColor];
_segmentedControl.layer.cornerRadius = ;
_segmentedControl.layer.masksToBounds = YES;
_segmentedControl.layer.borderWidth = ;
_segmentedControl.layer.borderColor = [UIColor whiteColor].CGColor;
[_segmentedControl addTarget:self action:@selector(indexDidChangeForSegmentedControl:)
forControlEvents:UIControlEventValueChanged];
}
return _segmentedControl;
}
- (WSFShopActivityListVC *)shopActivityListVC {
if (!_shopActivityListVC) {
_shopActivityListVC = [[WSFShopActivityListVC alloc] init];
}
return _shopActivityListVC;
} #pragma mark - UISegmentedControl协议方法
- (void)indexDidChangeForSegmentedControl:(UISegmentedControl *)sender {
switch(sender.selectedSegmentIndex){
case :
sender.selectedSegmentIndex = ; [self.shopActivityListVC.view removeFromSuperview];
[self.shopActivityListVC willMoveToParentViewController:nil];
[self.shopActivityListVC removeFromParentViewController]; break;
case :
sender.selectedSegmentIndex = ; [self.view addSubview:self.shopActivityListVC.view];
[self addChildViewController:self.shopActivityListVC];
[self.shopActivityListVC didMoveToParentViewController:self]; break; default:
break;
}
}

第三种实现方式:如上图所示,VCC专门作为一个控制器容器,轮流着将ViewA和ViewB添加到ViewC上面。
当然,还可以将前面两种思路综合起来使用,思路如下图:

第四种方式:如上如所示,使用了另外一个“专门的ViewController容器”VCC。结合第一种、第二种的思路应该是很好理解上图的,这里就不多说了。
使用注意事项:
1、对于SKStoreProductViewController这类控制器,设计者只允许将它模态跳转出来。此时使用addChildViewController是会报错的。
具体使用可以参看这片文章【https://www.cnblogs.com/cchHers/p/9099421.html】。
最后对于 UISegmentedControl控件的各种属性、各种方法的说明,我就先不往下写了。以后有时间在更新~
~暂时就这么多内容了。
分段控制器UISegmentedControl的使用、同一个控制器中实现多个View的切换、addChildViewController等方法的使用的更多相关文章
- UISegmentedControl字体大小,颜色,选中颜色,左边椭圆,右边直线的Button 解决之iOS开发之分段控制器UISegmentedControl
NSArray *segmentedArray = [NSArrayarrayWithObjects:STR(@"Mynews"),STR(@"Systemmes ...
- iOS开发之分段控制器(UISegmentedControl)
今天我们来说下iOS中的分段选择控制器UISegmentedControl,这一控件有什么作用呢 每个segment都能被点击,相当于集成了多个button 通常我们会点击不同的segment来切换不 ...
- Thinkphp5 的sesssion在同一个控制器不同的方法无法获取session的原因和对策
这一段在用thinkPHP5开发微信小程序接口的时候,在同一个控制器一个方法中存入session,在另一个方法中取出session,一直都是无法取出. 查阅各种资料得到原因:thinkPHP5里面的s ...
- Angularjs在控制器(controller.js)的js代码中使用过滤器($filter)格式化日期/时间实例
Angularjs内置的过滤器(filter)为我们的数据信息格式化提供了比较强大的功能,比如:格式化时间,日期.格式化数字精度.语言本地化.格式化货币等等.但这些过滤器一般都是在VIEW中使用的,比 ...
- 前端控制器是整个MVC框架中最为核心的一块,它主要用来拦截符合要求的外部请求,并把请求分发到不同的控制器去处理,根据控制器处理后的结果,生成相应的响应发送到客户端。前端控制器既可以使用Filter实现(Struts2采用这种方式),也可以使用Servlet来实现(spring MVC框架)。
本文转自http://www.cnblogs.com/davidwang456/p/4090058.html 感谢作者 前端控制器是整个MVC框架中最为核心的一块,它主要用来拦截符合要求的外部请求,并 ...
- IOS中导航控制器的代理及隐藏控制器刚出现时的滚动条
一.导航控制器的代理 1.UINavigationController的delegate属性 2.代理方法 1> 即将显示新控制器时调用 /* navigationController : 导航 ...
- SpringMVC传统风格控制器和基于注解的控制器
SpringMVC的DispatcherServlet 之前说过springMVC是使用Servlet作为控制器,就是这个用于调度的DispatcherServlet了.这个是servlet,可以根据 ...
- 使用容器控制器控制另外两个控制器的view交换
建三个UIViewController 的子控制器,其中一个为根控制器,另外两个控制器的视图作为切换对象 AppDelegate中代码 //AppDelegate.h中代码 #import <U ...
- PID控制器(比例-积分-微分控制器)- I
形象解释PID算法 小明接到这样一个任务: 有一个水缸点漏水(而且漏水的速度还不一定固定不变),要求水面高度维持在某个位置,一旦发现水面高度低于要求位置,就要往水缸里加水. 小明接到任务后就一直守在水 ...
随机推荐
- Python实现重命名一个文件夹下的图片
在网上查了一下python实现的图片重命名,工作中刚好用一下. # -*- coding:utf8 -*- import os path = '新建文件夹 (2)/' filelist = os.li ...
- SpringBoot-自动装载
1,SpringBoot里面有内置的tomcat容器. 2,SpringBoot是基于已有的东西创建的新的东西.核心:(AutoConfiguration)自动装载,Starter,Actuator, ...
- 前端框架vue学习笔记:环境搭建
兼容性 不兼容IE8以下 Vue Devtools 能够更好的对界面进行审查和调试 环境搭建 1.nodejs(新版本的集成了npm)[npm是node包管理 node package manager ...
- python函数1_参数,返回值和嵌套
函数 将重复的代码,封装到函数,只要使用直接找函数 函数可以增强代码的模块化和提高代码的重复利用率 函数的定义和调用 格式 def 函数名([参数,参数...]): 函数体 定义函数 import r ...
- 正则表达式regex回溯分析
正则表达式的回溯 现在我们来正式认识一下回溯.以字符串“abbc”为例,正则表达式为“ab{1,3}c”,再匹配的时候,a.b.b,匹配完成,这时候,正则表达式会继续用c和b进行比较,发现不符合,这时 ...
- 使用Dotfunsctor
设置Disable Control Flow.Disable Renaming.Disable String Encryption 为no,no为开启该功能 设置加密后输出的路i经 选择需要加密的ex ...
- iOS 开发之应用内弹出 App Store 应用界面
在APP内给其他APP做推广,经常用到在应用内弹出应用的APP #import <StoreKit/SKStoreProductViewController.h> 设置代理:<SKS ...
- 高级T-SQL进阶系列 (一)【下篇】:使用 CROSS JOIN 介绍高级T-SQL
[译注:此文为翻译,由于本人水平所限,疏漏在所难免,欢迎探讨指正] 原文链接:传送门. 性能考虑产生了笛卡尔积的这个CROSS JOIN操作符具有一些性能方面的问题需要考虑.因为SQL引擎需要将一个数 ...
- Nginx+Openssl实现HTTPs(重点)
[root@localhost ~]# rz -E //导入jdk源码包 z waiting to receive.**B0100000023 ...
- i.MX RT600之DSP开发环境调试篇
i.MX RT600的Cadence Xtensa HiFi 4 Audio DSP 是一个高度优化过的音频处理器,主频高达600MHz,专门为音频信号的编码.解码以及预处理和后处理模块而设计,功能十 ...