iOS控制器之基类设计
题记
在进入新公司后。经过这一个月的重构项目,终于把项目做到了个人相对满意的程度(还有一种不满意的叫老板的需求,提过多次意见也没用= =!)。在这次重构中按照以前的思路设计出了个人觉得比较适用的一个基类。在这里笔者会把此基类基本的设计说明一遍。
基类设计需求
1.在我们搭建框架之初一般会设计一个ViewController基类,并在基类ViewDidLoad中设置一个随机的背景颜色。并通过touch手势来进行界面的跳转,以此来设计最开始的一个界面跳转框架,并通过界面颜色的变幻来验证我们界面跳转是否有做到正常跳转。
2.接下来可能需要设计到的一个问题就是导航栏返回按钮的问题,因为系统自带的导航栏返回按钮相对来说不太好看。通常我们会将返回按钮进行自定义。在这里我们通过方法直接实现重定义导航栏左边按钮达到我们想要的效果
3.在很多时候我们对View子视图进行布局时,可能子视图的范围偶尔会超时View视图bounds范围。此时可能还需要设计一个方法来让View的子视图即使在View的bounds范围之外也能得以呈现。
Vc基类设计实现
对于上述需求,其中需求1最好解决。我们普遍的做法是写一个自己的工具类,然后在viewDidLoad中通过工具类生成一个随机的颜色作为基类视图的背景色,从而查看是否达到跳转目的。
self.view.backgroundColor = [BQTools randomColor];
接下来是自定义返回按钮的问题,(目前大部分APP都是用导航栏推出下个控制器,如果用present模态推出。那可忽略此段内容)。基于最方便的实现方法即在VIew视图加载时,直接给导航栏生成一个左侧栏item。并实现其点击方法达到导航栏pop的目的。此处的“back”为自定义的返回按钮视图
UIBarButtonItem * leftBarItem = [[UIBarButtonItem alloc] initWithImage:[[UIImage imageNamed:@"back"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] style:UIBarButtonItemStylePlain target:self action:@selector(leftBarItemAction:)];
self.navigationItem.leftBarButtonItem = leftBarItem;
这样的情况是方便的解决的需求2问题,但衍生出一个新问题,即当导航栏的第一控制器也会存在一个左侧栏item,并实现了pop方法。所以我们需要在这里再加上一个判定情况,使其在导航栏第一控制器不存在此item。所以更新后的代码如下
if ([self.navigationController.viewControllers indexOfObject:self] != 0) {
UIBarButtonItem * leftBarItem = [[UIBarButtonItem alloc] initWithImage:[[UIImage imageNamed:@"back"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] style:UIBarButtonItemStylePlain target:self action:@selector(leftBarItemAction:)];
self.navigationItem.leftBarButtonItem = leftBarItem;
}
最后是View子视图的布局问题,很多时候我们都会有超出视图范围以外的子视图存在,此时就需要在View视图上布局一个scrollview来达到视图滚动查看View视图bounds子视图的目的。既然存在这种情况,那我们在这里就可以仿照cell的情况 直接给一个contentView(为ScrollView)来做为子视图容器。最后再通过方法遍历直接获取子视图的frame通过比较修改contentView的展示区域,此时所有的子视图应该添加到contenView之上
//生成contentView
self.automaticallyAdjustsScrollViewInsets = NO;
self.automaticallyAdjustsScrollViewInsets = NO;
self.contentView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 64, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height - 64)];
[self.view addSubview:self.contentView];
self.contentView.contentSize = self.contentView.bounds.size;
//在viewWillAppear中去判断修改contentView的展示范围
CGFloat contentHeight = 0;
NSArray * subViews = self.contentView.subviews;
for (UIView * view in subViews) {
if (CGRectGetMaxY(view.frame) > contentHeight) {
contentHeight = CGRectGetMaxY(view.frame);
}
}
//笔者项目主要是上下滚动,如视图可能超出视图右侧,也能以同样方式实现其效果
if (contentHeight > self.contentView.bounds.size.height) {
self.contentView.contentSize = CGSizeMake(self.contentView.bounds.size.width, contentHeight);
}
注意
有部分控制器可能会存在导航栏背景色透明的情况,此时若导航栏透明contentView的布局就需要从0,0处开始,所以还需要给出方法对contentView的frame进行调整。关于导航栏的背景色调整笔者使用的是第三方的导航栏
使用范围、场景
以上基类只是一个最基本常用的原型,可能在实际项目中还需要拓展一些其他的共通属性,比如主题色,导航栏隐藏,标签栏出现隐藏等情况,所以在项目中使用时,还需要根绝自己的实际需求进行修改。另外作为第三种需求来说,布局直接超出View视图bounds范围的话一般是因为UI切图时给出的图高度较长。所以在笔者的项目中使用等比例适配(并非宽高比,而是纯基于宽度的对比比例在进行设计)来搭配此基类,效果较好(因为笔者进行完全等比例适配,所以图片同样会有缩放情况,在此种情况下如不是用重绘,可能会存在效率上的浪费)。但如果是使用masonry进行布局,可能就不太需要按照笔者的基类进行设计了。
后记
对于控制器基类的设计,个人有个人的理解。笔者在这里抛出自己的设计思路及部分代码封装,希望各位能指点交流。如上述有何错误之处,请指正。谢谢!
iOS控制器之基类设计的更多相关文章
- iOS 基于MVC设计模式的基类设计
iOS 基于MVC设计模式的基类设计 https://www.jianshu.com/p/3b580ffdae00
- iOS Foundation 框架基类
iOS Foundation 框架基类 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转 ...
- [theWord] 一种英文字典的基类设计
theWord --- 一种英文字典的基类设计 使用场景 想写一个应用,来记录自己背单词时候,对每个单词的记忆状况之类的东西.至于为什么做这个,试过了一些背单词软件,并不觉得好用,自己做一个吧. 那么 ...
- 以人类 Person 为基类设计学生类 Student 和教师类 Teacher
学习内容:实验二以人类 Person 为基类设计学生类 Student 和教师类 Teacher 示例代码: package 实验二; import java.util.Scanner; class ...
- 实验二——以点类 Point 为基类设计圆类 Circle
学习内容:以点类 Point 为基类设计圆类 Circle 示例代码: package 实验二; import java.util.Scanner; class Point{//父类Point pri ...
- 【iOS】UIViewController基类的实现
继承是面向对象编程语言的三大特性之一,写好基类会给App的开发带来极大的方便.在iOS开发中,一般一个页面就对应一个ViewController,ViewController在开发中用的也很多,写一个 ...
- 读书笔记 effective c++ Item 7 在多态基类中将析构函数声明为虚析构函数
1. 继承体系中关于对象释放遇到的问题描述 1.1 手动释放 关于时间记录有很多种方法,因此为不同的计时方法创建一个TimeKeeper基类和一些派生类就再合理不过了: class TimeKeepe ...
- 无线客户端框架设计(3):基类的设计(iOS篇)
本文代码:YoungHeart-Chapter-03.zip 没有基类的App都不是好App. 因为iOS使用的是mvc模式的开发模式,所以,业务逻辑基本都在每个页面相应的ViewController ...
- IDEA项目搭建十四——Web站点Controller基类及布局页静态资源设计
一.简介 站点搭建完成后,编写页面时一般会有如下几个需求 1.嵌套静态页面时有很大一部分通用代码,如css.js这部分可以使用thymeleaf的局部片段代码块组成 2.这些静态资源默认放在程序中,但 ...
随机推荐
- Array.prototype.slice.call(arguments)
Array.prototype.slice.call(arguments)能够将具有length属性的对象转化为数组, 可以理解为将arguments转化成一个数组对象,让它具有slice方法 如: ...
- msysgit之git bash方便的复制粘贴,默认工作目录,窗口大小,提高速度等小窍门
桌面图标点鼠标右键,选择属性,修改工作目录到自己的git目录: 打开快速编辑,这时候鼠标左键可以随意选取文本,enter键复制.鼠标右键是粘贴.另外,粘贴的快捷键是 inerst键 修改默认窗口大小 ...
- 在virtualbox中安装CentOS-7
当初才接触linux的时候,因为条件限制,只能在虚拟机中安装linux系统使用,由于是小白,爬了好多坑.于是决定写一篇关于在虚拟机中安装linux系统的博客.一是为了巩固自己的知识,二是希望能够对新手 ...
- TextField文本框
1)失去第一响应者状态方法(即关闭键盘) 要先将视图view的底层类设置为UIControl类 再设置view的touch down事件,在事件中写入以下方法 [self.textField resi ...
- Linux操作系统备份之三:通过二进制拷贝(dd)方式实现Linux操作系统数据的备份
前面有两篇文章,<Linux操作系统备份之一:使用LVM快照实现Linux操作系统数据的在线备份>和<Linux操作系统备份之二:通过tar拷贝分区实现Linux操作数据的在线备份& ...
- 今天学了递归,感觉好复杂啊/(ㄒoㄒ)/~~
honio塔思路: 第一步 把A上的n-1个圆盘借助C移到B上: 第二步 把A上的一个圆盘移到C上: 第三步 把B上的n-1个圆盘借助A移到C上. 这显然符合递归的两个条件: ①具备边界条件:只有1个 ...
- 一张图轻松搞懂javascript event对象的clientX,offsetX,screenX,pageX区别
总是会被javascript的event对象的clientX,offsetX,screenX,pageX 弄得头晕,于是决定做个图来区分一下(画得我手那个酸呀....) 先总结下区别: event.c ...
- 我的第一个FluentNHibernate例子
刚刚接触NHibernate和FluentNHibernate,所以最好的方法是从一个简单的例子入手. 开发环境考虑到是实际情况还有好多朋友没有用VS2015,就用VS2013withUpdate5吧 ...
- paper 130:MatLab分类器大全(svm,knn,随机森林等)
train_data是训练特征数据, train_label是分类标签.Predict_label是预测的标签.MatLab训练数据, 得到语义标签向量 Scores(概率输出).1.逻辑回归(多项式 ...
- Keras学习~试用卷积~跑CIFAR-10
import numpy as np import cPickle import keras as ks from keras.layers import Dense, Activation, Fla ...