App开发流程之通用宏定义及头文件
工欲善其事,必先利其器。
在正式实现各种炫酷的功能和UI前,做好准备工作是提高后续开发效率的必经之路。
所以,这个系列,我不是在各种堆技术,更关注的是“兵马动”之前的“粮草行”,有些繁琐,但当清晰理出整个脉络,后续的工作只是在良好的基础和框架上无限扩展和优化。
宏定义,是开发过程中提高效率的有效工具。很有必要归纳一些全局通用的宏定义,以便简单高效的使用。
如下,整理了一些通用宏定义,应该是开发必备的:
#pragma mark -- 设置全局尺寸宏
#define StatusBarHeight 20
#define NaviBarHeight 44
#define TabBarHeight 49 #define KeyboardEngHeight 216
#define KeyboardHansHeight 252 #pragma mark -- 设置全局颜色宏
//下列宏定义,只作为一种设备适配参考方案
#define StatusBarColor [UIColor blackColor]
#define NaviBarColor [UIColor whiteColor]
#define NaviBarTitleSelectedColor COLOR(255, 120, 100)
#define NaviBarTitleUnselectedColor COLOR(100, 100, 100)
#define NaviBarShadowColor COLOR(230, 230, 230) #define NaviBarTitleFontSize ((DeviceIsNotRetina || DeviceIsiPhone4s || DeviceIsiPhone5) ? 17 : 19) #define NaviBarTitleAttributes [NSDictionary dictionaryWithObjectsAndKeys:FONTAppliedFixed(NaviBarTitleFontSize),NSFontAttributeName,NaviBarTitleUnselectedColor, NSForegroundColorAttributeName, nil] #define NaviItemTextFontSize ((DeviceIsNotRetina || DeviceIsiPhone4s || DeviceIsiPhone5) ? 14 : 16)
#define NaviItemTextGrayColor COLOR(140, 140, 140) #define NaviBottomLineColor NaviBarTitleSelectedColor #pragma mark -- 字符串本地化宏
#define LocalizedString(String) NSLocalizedString(String,String) #pragma mark -- 获取设备宽度和高度
//会随着应用内部横屏和竖屏变化
#define DeviceSize [UIScreen mainScreen].bounds.size
#define DeviceWidth DeviceSize.width
#define DeviceHeight DeviceSize.height #pragma mark -- 判断是否iPhone4,4s,5,6,plus,iPad
//不会随着应用内部横屏和竖屏变化
#define DeviceCurrentModeSize [UIScreen mainScreen].currentMode.size
#define DevicePortraitModeSize (DeviceCurrentModeSize.width < DeviceCurrentModeSize.height ? DeviceCurrentModeSize : CGSizeMake(DeviceCurrentModeSize.height, DeviceCurrentModeSize.width))
#define DeviceIsNotRetina CGSizeEqualToSize(DevicePortraitModeSize, CGSizeMake(320, 480))
#define DeviceIsiPhone4s CGSizeEqualToSize(DevicePortraitModeSize, CGSizeMake(640, 960))
#define DeviceIsiPhone5 CGSizeEqualToSize(DevicePortraitModeSize, CGSizeMake(640, 1136))
//6s与6同尺寸
#define DeviceIsiPhone6 CGSizeEqualToSize(DevicePortraitModeSize, CGSizeMake(750, 1334))
//6s Plus 与 6Plus同尺寸(部分机型实际上只有6s的bounds.size)
#define DeviceIsiPhone6plus (CGSizeEqualToSize(DevicePortraitModeSize, CGSizeMake(1125, 2001)) || CGSizeEqualToSize(DevicePortraitModeSize, CGSizeMake(1242, 2208)))
//在模拟器上调试,可能会遇到非Retina分辨率的情况
#define DeviceIsiPad (CGSizeEqualToSize(DevicePortraitModeSize, CGSizeMake(768, 1024)) || CGSizeEqualToSize(DevicePortraitModeSize, CGSizeMake(1536, 2048)) || CGSizeEqualToSize(DevicePortraitModeSize, CGSizeMake(1024, 1366)) || CGSizeEqualToSize(DevicePortraitModeSize, CGSizeMake(2048, 2732))) #pragma mark -- 判断设备操作系统整数版本号
//当前系统版本号取得仍为浮点型
#define DeviceIOSVersion [[[UIDevice currentDevice] systemVersion] floatValue]
#define DeviceIOSVersionIs(x) (DeviceIOSVersion >= x && DeviceIOSVersion < x+1 ? YES : NO)
#define DeviceIOSVersionAbove(x) (DeviceIOSVersion >= x ? YES : NO) #pragma mark -- 根据设备,计算标注图中当前缩放尺寸(标注图版本:375宽度) iPad以iPhone6为标准显示
//下列宏定义,只作为一种设备适配参考方案
#define ResizeSideBase6(s) (DeviceIsiPad ? s : (DeviceWidth * s / 375)) #pragma mark -- 只根据设计图(标注图版本:375宽度)的宽度等比缩放
#define ResizeSideBase375(s) (DeviceWidth * s / 375) #pragma mark -- 设置自定义字体
#define FontName1 @"FZY3JW--GB1-0"//方正准圆ttf字体名称
#define FontName2 @"Helvetica"
#define FontName3 @"Helvetica-Bold" //固定字体大小
#define FONTAppliedFixed(n) [UIFont systemFontOfSize:n]
#define FONTAppliedBoldFixed(n) [UIFont boldSystemFontOfSize:n]
#define FONTFZZYFixed(n) [UIFont fontWithName:FontName1 size:n]
#define FONTHelveticaFixed(n) [UIFont fontWithName:FontName2 size:n]
#define FONTHelveticaBoldFixed(n) [UIFont fontWithName:FontName3 size:n] //下列宏定义,只作为一种设备适配参考方案
//根据设备,计算显示字体(标注图版本:375宽度) iPad以iPhone6为标准显示
#define FONTAppliedBase6(n) (DeviceIsiPhone6plus ? FONTAppliedFixed(n+0.5) : (DeviceIsiPhone6 || DeviceIsiPad ? FONTAppliedFixed(n) : FONTAppliedFixed(n-1)))
#define FONTAppliedBoldBase6(n) (DeviceIsiPhone6plus ? FONTAppliedBoldFixed(n+0.5) : (DeviceIsiPhone6 || DeviceIsiPad ? FONTAppliedBoldFixed(n) : FONTAppliedBoldFixed(n-1))) #define FONTHelveticaBase6(n) (DeviceIsiPhone6plus ? FONTHelveticaFixed(n+0.5) : (DeviceIsiPhone6 || DeviceIsiPad ? FONTHelveticaFixed(n) : FONTHelveticaFixed(n-1)))
#define FONTHelveticaBoldBase6(n) (DeviceIsiPhone6plus ? FONTHelveticaBoldFixed(n+0.5) : (DeviceIsiPhone6 || DeviceIsiPad ? FONTHelveticaBoldFixed(n) : FONTHelveticaBoldFixed(n-1))) #pragma mark -- 加载图片宏(下列方法频繁IO,不缓存图片):
#define LOADIMAGE(name) [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:name ofType:nil]]
#define LOADIMAGEWITHTYPE(name,type) [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:name ofType:type]] #pragma mark -- 设置16进制RGB颜色(格式:RRGGBB)
#define COLORWITHRRGGBBA(RRGGBB, A) [UIColor colorWithRed:((float)((RRGGBB & 0xFF0000) >> 16))/255.0 green:((float)((RRGGBB & 0xFF00) >> 8))/255.0 blue:((float)(RRGGBB & 0xFF))/255.0 alpha:A]
#define COLORWITHRRGGBB(RRGGBB) COLORWITHRRGGBBA(RRGGBB, 1.0) #pragma mark -- 设置10进制RGB颜色
#define COLORWITHRGBA(R, G, B, A) [UIColor colorWithRed:R/255.0 green:G/255.0 blue:B/255.0 alpha:A]
#define COLOR(R, G, B) COLORWITHRGBA(R, G, B, 1.0) #define COLORWITHIMAGE(name) [UIColor colorWithPatternImage:LOADIMAGE(name)] #pragma mark -- 角度弧度转换
#define DegreesToRadian(x) (M_PI * x / 180.0)
#define RadianToDegrees(radian) (radian * 180.0 / M_PI) #pragma mark -- log输出控制宏
#ifdef DEBUG
#define LOG(...) NSLog(__VA_ARGS__);
#define LOG_METHOD NSLog(@"%s", __func__);
#else
#define LOG(...) ;
#define LOG_METHOD ;
#endif #pragma mark -- 弱引用宏定义
#define WS(weakSelf) __weak typeof(self) weakSelf = self;
说明如下:
1.[UIScreen mainScreen].bounds.size会随着横屏和竖屏变化,[[UIScreen mainScreen] currentMode].size不会随之改变。
例如,将工程General中横屏勾选上,在iPhone6s上运行,一开始为竖屏(375,667),应用旋转到横屏后,前者宽高对调(667,375);后者始终为(750,1334)
2.DeviceIsiPhone6plus 判断是否为6Plus时候,遇到过一些分辨率实际为(1125, 2001)的测试机,也就是说bounds.size为(375,667),猜测是翻新机
3.DeviceIsiPad判断iPad时候,多了非Retina分辨率的比对。因为在iPad上调试仅为iPhone类型的应用,会遇到此类型的分辨率
4.ResizeSide和FONT系列的宏定义,提供了宽度和字体用代码适配多设备的简单参考方案,当然Masonry类库是代码适配设备最好的方案,这里只是用于便捷使用
5.LOADIMAGE宏定义,采用了频繁IO的方式来加载图片资源,目的是避免内存的缓存长时间占用。建议需要保留对象时候,增加属性或者变量引用即可
6.若引用宏定义中,__weak typeof(self) weakSelf = self;写法中的typeof也可以替换为旧版__typeof,不过建议使用新的写法,即typeof
着重记录一下自定义字体的使用
之前在配置Info.plist文件时候,添加了字体的键值对,现在就可以派上用途了。
1.先将.ttf字体添加到项目中,然后在Info.plist文件的Source code中,在UIAppFonts键下增加如下代码:
<key>UIAppFonts</key>
<array>
<string>fzzy.ttf</string>
</array>
当然,也可以在列表模式下,找到Fonts provided by application键,然后添加一个item,将ttf文件的名称填入其中。
2.在合适的地方(例如AppDelegate的应用启动后的代理方法中)使用如下代码:
for (NSString* familyName in [UIFont familyNames]) {
LOG(@"familyName : %@", familyName);
for (NSString* fontName in [UIFont fontNamesForFamilyName:familyName]) {
LOG(@"fontName : %@", fontName);
}
}
3.运行应用后,在控制台查看字体输出log,既然用的是fzzy字体,所以实际名称应该类似。所以找到了“FZY3JW--GB1-0”这样的字体名称
4.可以查看FONTFZZYFixed宏定义的字体显示效果
需要注意的是,同一字体族中,细体、粗体、斜体等,都是不同的字体名称,可以理解为在使用不同的字体。一个ttf字体文件,一般只有一种字体,具体情况需要查看控制台输出的字体log。
头文件的使用
在Supporting Files文件目录下创建头文件:

我将通用宏定义放入了CommonHeader.h,便于统一管理以及扩充。
类似的,不同类型宏定义,建议组织为不同头文件,例如:StringsHeader.h,ImagesHeader.h,URLsHeader.h。
最后,将所有头文件统的引用统一加入到预编译头文件中PrefixHeader.h全局生效。
============================================
2016.09.21更新
补充记录一下#define和const的比较
#define宏定义可以预编译一些代码,简化逻辑,提高复用率。但是容易被覆盖,Xcode会提示。
const常量定义,是运行时分配内存和初始化,不允许修改,但是只能适用于常用数据类型的常量。
大量的宏定义肯定是会影响编译效率乃至应用体积的,配合适用应该是最佳的。
const的用法有如下几种:
1.const CGFloat a = 1.2;
2.const NSString *b = @"b";
3.NSString const *c = @"c";
4.NSString *const d = @"d";
理解规律就是:const右边的部分不允许再修改。
第一种,a不能修改;第二、三种一样,都是*b、*c不能修改,即地址;第四种,是d不能修改,即内容。
base项目已更新:git@github.com:ALongWay/base.git
App开发流程之通用宏定义及头文件的更多相关文章
- 零基础逆向工程16_C语言10_宏定义_头文件_内存分配_文件读写
#define 无参数的宏定义的一般形式为:#define 标识符 字符序列 如:#define TRUE 1 注意事项: 1.之作字符序列的替换工作,不作任何语法的检查 2.如果宏定义不当,错误要到 ...
- iOS开发ARC与MRC下单例的完整写法与通用宏定义
#import "XMGTool.h" /** * 1:ARC下的完整的单例写法:alloc内部会调用+(instancetype)allocWithZone:(struct _N ...
- 20个可以帮你简化iOS app开发流程的工具
这里推荐20个可以帮你简化iOS app开发流程的工具.很多开发者都使用过这些工具,涉及原型和设计.编程.测试以及最后的营销,基本上涵盖了整个开发过程. 原型和设计 有了一个很好的创意后,你要做的不是 ...
- iOS开发之工具篇-20个可以帮你简化移动app开发流程的工具
如果想进入移动app开发这个领域,你总能从别的开发者或者网上或者书上找到各种各样的方法和工具,对于新手来说,还没有摸清门路就已经陷入迷茫了.这里推荐20个可以帮你简化app开发流程的工具.很多开发者都 ...
- app开发流程有哪些
app开发流程是需求方和供求方相互协调的过程,一般分为需求分析.功能设计.功能实现.项目测试.上线等几个步骤,下面我们就来一起看看ytkah团队进行app开发各个流程主要做哪些事情,让您对app开发设 ...
- c++中const变量定义与头文件包含的有关问题
在使用C++进行程序开发的时候,有个常识我们很熟悉,就是把类的定义写在.h文件中,把类的具体实现写在.cpp文件中.这毫无疑问是对的.但我们很少去思考为什么要这样做,本文结合自己的学习体会,对头文件及 ...
- iOS开发中的常用宏定义
在iOS开发的过程中合理的使用宏定义能够极大提高编码的速度,下面是一些常用的宏定义,部分内容来自互联网 Log // 调试状态, 打开LOG功能 #ifdef DEBUG #define GLLog( ...
- 深度讲解智能硬件手机APP开发流程
常州做APP开发公司紫竹云科技分析,智能硬件产品的软件开发,除了APP和后台之外还有一个固件端的开发,由于固件是要运行产品上的,不过此时的硬件也是刚开始进行研发,所以是无法提供硬件来运行固件的.因此在 ...
- iOS之 开发常用到的宏定义
不久前做过一个小项目种用到了就记录下来方便自己以后使用,一个非常实用的宏定义来打印函数名称等 #ifdef DEBUG #define DebugLog(fmt, ...) NSLog((@" ...
随机推荐
- [Latex]实现行内高亮
Latex的行内高亮 前两天想要在做的小操作系统实验指导书里使用行内高亮,一开始虽然有命令 \mint{Language}|contents| 但是无奈只能实现跳行高亮,即不能实现行内高亮.即代码高亮 ...
- 学期总结ngu
不知不觉一年就过去了,真可谓光阴似箭,日月如梭,在这一年里,我成长了许多,懂得了如何跟队友合作,提高了我的交际能力,懂得了许多课本知识,增进了我的编写能力.最重要的是学会了总结经验,这无疑是我这一年里 ...
- MyEclipse搭建SSM框架(Spring+MyBatis+SpringMVC)
待写. 参考网址 http://www.cnblogs.com/Joetao/articles/4544572.html http://www.cnblogs.com/verlen11/p/53497 ...
- P6 EPPM R16.1安装与配置指南(二)
P6 EPPM R16.1安装与配置指南(一) http://www.cnblogs.com/endv/p/5634620.html P6 EPPM R16.1安装与配置指南(二) 环境变量配置 新建 ...
- 甲骨文白桃花心木P6 EPPM 8.2项目点提供样本
甲骨文白桃花心木样例代码 除非明确确定,这里的示例代码不是认证或Oracle支持;它只是用于教育或测试的目的. 你必须接受 许可协议下载此示例代码. 接受 许可协议 | 下降 许可协议 的名字 ...
- 重构第16天 封装条件(Encapsulate Conditional)
理解:本文中的“封装条件”是指条件关系比较复杂时,代码的可读性会比较差,所以这时我们应当根据条件表达式是否需要参数将条件表达式提取成可读性更好的属性或者方法,如果条件表达式不需要参数则可以提取成属性, ...
- 通过js获取前台数据向一般处理程序传递Json数据,并解析Json数据,将前台传来的Json数据写入数据库表中
摘自:http://blog.csdn.net/mazhaojuan/article/details/8592015 通过js获取前台数据向一般处理程序传递Json数据,并解析Json数据,将前台传来 ...
- jquery实现全选功能
主要是模拟一些网页中的表格实现全选功能. <form> 你爱好的运动是: <input type="checkbox" id="Check" ...
- 小知识~LocalDB在IIS上如何成功配置
LocalDB使用确实方便,它不像SQLSERVER那么重,对一个测试的DEMO或者并发量不大的项目可以使用它,但在进行IIS部署时,可能会出现一些问题,即你的IIS可能没有权限访问你的LocalDB ...
- Redis持久化-数据丢失及解决
Redis的数据回写机制 Redis的数据回写机制分同步和异步两种, 同步回写即SAVE命令,主进程直接向磁盘回写数据.在数据大的情况下会导致系统假死很长时间,所以一般不是推荐的. 异步回写即BGSA ...