题记

在进入新公司后。经过这一个月的重构项目,终于把项目做到了个人相对满意的程度(还有一种不满意的叫老板的需求,提过多次意见也没用= =!)。在这次重构中按照以前的思路设计出了个人觉得比较适用的一个基类。在这里笔者会把此基类基本的设计说明一遍。

基类设计需求

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控制器之基类设计的更多相关文章

  1. iOS 基于MVC设计模式的基类设计

    iOS 基于MVC设计模式的基类设计 https://www.jianshu.com/p/3b580ffdae00

  2. iOS Foundation 框架基类

    iOS Foundation 框架基类 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转 ...

  3. [theWord] 一种英文字典的基类设计

    theWord --- 一种英文字典的基类设计 使用场景 想写一个应用,来记录自己背单词时候,对每个单词的记忆状况之类的东西.至于为什么做这个,试过了一些背单词软件,并不觉得好用,自己做一个吧. 那么 ...

  4. 以人类 Person 为基类设计学生类 Student 和教师类 Teacher

    学习内容:实验二以人类 Person 为基类设计学生类 Student 和教师类 Teacher 示例代码: package 实验二; import java.util.Scanner; class ...

  5. 实验二——以点类 Point 为基类设计圆类 Circle

    学习内容:以点类 Point 为基类设计圆类 Circle 示例代码: package 实验二; import java.util.Scanner; class Point{//父类Point pri ...

  6. 【iOS】UIViewController基类的实现

    继承是面向对象编程语言的三大特性之一,写好基类会给App的开发带来极大的方便.在iOS开发中,一般一个页面就对应一个ViewController,ViewController在开发中用的也很多,写一个 ...

  7. 读书笔记 effective c++ Item 7 在多态基类中将析构函数声明为虚析构函数

    1. 继承体系中关于对象释放遇到的问题描述 1.1 手动释放 关于时间记录有很多种方法,因此为不同的计时方法创建一个TimeKeeper基类和一些派生类就再合理不过了: class TimeKeepe ...

  8. 无线客户端框架设计(3):基类的设计(iOS篇)

    本文代码:YoungHeart-Chapter-03.zip 没有基类的App都不是好App. 因为iOS使用的是mvc模式的开发模式,所以,业务逻辑基本都在每个页面相应的ViewController ...

  9. IDEA项目搭建十四——Web站点Controller基类及布局页静态资源设计

    一.简介 站点搭建完成后,编写页面时一般会有如下几个需求 1.嵌套静态页面时有很大一部分通用代码,如css.js这部分可以使用thymeleaf的局部片段代码块组成 2.这些静态资源默认放在程序中,但 ...

随机推荐

  1. Windows Phone 十五、HttpWebRequest

    Windows 运行时中支持网络资源访问的对象:HttpWebRequest 对象 发送 GET/POST 请求,HttpHelper 封装,超时控制. HttpClient 对象 发送 GET/PO ...

  2. linux更改 DNS 的一般方式

    一.第一种方法(常规方法) 在 Linux (笔者用fedora) 下当使用 NetworkManager时,更改 DNS 的一般方式: 修改 /etc/resolv.conf 文件, 添加 &quo ...

  3. Javascript 中判断对象为空

    发现了一个巧妙的实现: 需要检查一个对象(Object)是否为空,即不包含任何元素.Javascript 中的对象就是一个字典,其中包含了一系列的键值对(Key Value Pair).检查一个对象是 ...

  4. 利用git+hugo+markdown 搭建一个静态网站

    利用git+hugo+markdown 搭建一个静态网站 一直想要有一个自己的文档管理系统: 可以很方便书写,而且相应的文档很容易被分享 很方便的存储.管理.历史记录 比较方面的浏览和查询 第一点用M ...

  5. 关于xfce桌面程序启动失败

    当双击桌面图标的时候,出现如下错误信息:Process org.xfce.FileManager exited with status 1 于是做出如下尝试: 1. ps aux | grep Fil ...

  6. Spring Batch学习笔记三:JobRepository

    此系列博客皆为学习Spring Batch时的一些笔记: Spring Batch Job在运行时有很多元数据,这些元数据一般会被保存在内存或者数据库中,由于Spring Batch在默认配置是使用H ...

  7. push or get File or Folder using scp wrapped with expect and bash

    经常需要把服务器的某些文件传到 Mac,或者获取 Mac 的一些文件到服务器.尽管有很多命令scp, ftp, rsync都可以,霸特每次都有敲好长的命令,好烦,而且还要输入密码.所以想着 wrap ...

  8. MessageReceiver

    class MessageReceiver { private RelayEngine<MessageCollection> _MessageRelayEngine; private st ...

  9. hadoop多硬盘配置注意点

    [一].实验环境 1.1.环境 hadoop 2.6.0 namenode 2个  各增加 2个1T硬盘 datanode   3个  各增加3个1T硬盘 1.2.挂载硬盘 fdisk    分区 ( ...

  10. busybox的编译、使用及安装

    转载于:http://blog.sina.com.cn/wyw1976 busybox是什么? (1)busybox是Linux上的一个应用程序(application),即只有一个ELF文件头. ( ...