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进行布局,可能就不太需要按照笔者的基类进行设计了。

后记

对于控制器基类的设计,个人有个人的理解。笔者在这里抛出自己的设计思路及部分代码封装,希望各位能指点交流。如上述有何错误之处,请指正。谢谢!

时间: 2024-10-05 15:58:32

iOS控制器之基类设计的相关文章

Android基类设计方法详解

1 为什么要设计基类 为什么要给程序设计基类呢?主要是出于2个原因,一是方便代码编写,减少重复代码和冗余逻辑,优化代码:二是优化程序架构,降低耦合度,方便拓展.修改. ok,编写代码是程序员的第一步,那么第二步就是要编写高质量的代码,代码能实现功能是一方面,写的优美则是另一方面,这也是我们所有攻城狮们应该追求的境界. 2 设计基类的基本思路 那么,哪些东西我们需要抽象到基类中呢? 2.1 重复的代码:如果一个逻辑是大多数子类都需要使用的 2.2 臭而长的代码:典型的findviewbyid.To

iOS Foundation 框架基类

太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:太阳火神的漂亮人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS.Android.Html5.Arduino.pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 基类 Title Topic Date NSObject Class Reference Data Types & Collections

BaseMongo基类设计

为进一步完善框架应用,本次系列文章主要是介绍如何完善架构功能,以及如何应用架构做一些具体的应用开发.本系列课程可以在github上找到相应资源,具体每篇文章中都会提供链接. 本次介绍的主要是mongo基类的设计,以及应用.相关请查看文章下面链接下载http://5xpan.com/fs/7hueanfgd6h350fe4/(下载链接有收益,请原谅有广告). 如果你嫌弃慢的话,也可以直接去github(https://github.com/tnodejs/BaseMongodb) 主要函数结构 私

面向对象程序设计——抽象基类,访问控制与继承,继承中的类作用域,拷贝函数与拷贝控制

一.抽象基类 1)纯虚函数 和普通的虚函数不同,一个纯虚函数无须定义.我们通过在函数体的位置(即在声明语句的分号之前)书写=0就可以将一个虚函数说明为纯虚函数.其中,=0只能出现在类内部的虚函数声明语句处. 值得注意的是,我们也可以为纯虚函数提供定义,不过函数体必须定义在类的外部.也就是说,我们不能在类的内部为一个=0的函数提供函数体. 2)含有纯虚函数的类是抽象基类 含有(或者未经覆盖直接继承)纯虚函数的类是抽象基类.抽象基类负责定义接口,而后续的其他类可以覆盖该接口.我们不能直接创建一个抽象

iOS数据持久化之二——归档与设计可存储化的数据模型基类

iOS数据持久化之二--归档与设计可存储化的数据模型基类 一.引言 在上一篇博客中,我们介绍了用plist文件进行数据持久化的方法.虽然简单易用,但随着开发的深入,你会发现,这种方式还是有很大的局限性.试想,如果我们可以将用户的登录返回信息模型,游戏中角色的属性信息模型进行直接的持久化存取,那是不是非常爽的事,幸运的是,我们可以通过归档,来设计一个这样的数据模型. 二.先来精通归档吧 归档也是iOS提供给开发者的一种数据存储的方式,事实上,几乎所有的数据类型都可以通过归档来进行存取.其存储与读取

从设计基类及其派生类看继承关系

继承能够定义可重用.扩展或修改父类行为的子类.但基类的静态构造函数.实例构造函数和析构函数不能被派生类继承. 在下面实例中,定义一个基类Publication用于表示任何类型的出版物以及派生至Publication的其他类型Book类,由此也可以扩展为定义其他类型如:Magazine.Journal.Newspaper和Article. 在设计基类Publication时我们必须考虑到如下关系: 1.要在基类中添加哪些成员 2.基类是否用作派生类模板的抽象基类 3.类层次结构的扩展空间大小,要开

软件设计新趋势,云基类该如何实现?

基于云基类的框架设计-2015年末随想2015年马上要结束了,展望2016,对软件开发和设计有些感谢,想和园子里的朋友交流交流. 想想中的开发场景: 一个好的软件架构设计师设计一套好的架构,这套架构运行与云中的服务器,基于架构开发的人员通过“web service” ,“wcf”或其他还没创造出来的技术引用到本地,开发人员在此架构上完善自己的具体业务需求.(“web service” ,“wcf”,之所以加引号,是无法实现目前的想法) 特点:(1)所有的基类实现代码都在云服务器上,开发人员无法接

Android App框架设计之编写基类BaseActivity

Android App框架设计之编写基类BaseActivity 编写基类BaseActivity - OOP里面子类里面能够共享父类的方法,提高代码的可复用性 - 基类的编写要根据实际项目的情况,有的可能很简单 比如只是显示 "关于" 信息, 业务功能非常少 你可以不用继承基类进行扩展 BaseActivity继承Activity 还是 FragmentActivity 还是其它? 也是根据你的技术要求,因为解决问题的方法有很多种,或者你根本不用写基类也能完成工作. 我们的目的是编写

基类的设计

鉴于json数据传输的使用,可以在实体类基础上设计基类 public abstract class BaseModel implements Serializable{  private static final long serialVersionUID=1L;      //==============json===============//  /**   * 从JSONObject中读取字段   * @param obj   */  public BaseModel parseJson(