在iPhone开发的过程中,很多人会感慨水果公司提供的可用控件之少。为了提高项目的开发效率,有时候不得不在原有控件的基础上,自己实现一些功能,然后把它制作成函数库供其它程序使用。这样做的好处是:
1.提高了代码的复用率,提高开发效率。
2.提搞了核心技术的保密程度。
函数库分为静态库和动态库两种,所谓静态和动态是相对编译期和运行期的:静态库在程序编译时会被链接到目标代码中,程序运行时将不再需要改静态库;而动态库在程序编译时并不会被链接到目标代码中,只是在程序运行时才被载入,因为在程序运行期间还需要动态库的存在。
But,水果公司禁止在iPhone中使用外部框架或动态链接库。恩,贱是没有极限的~~~所以,我们要重用代码(第三方库或自己的代码)可以采用下面的方法:
1. 直接将代码加入项目.这无疑是一种巨2的方式,因为假设你的一段代码被五个项目共享,不幸的你(就像我经常干的那样)发现了一个小bug,那么,你将怎么办?你不得不去修改这五个地方!!!
2.使用静态库。这是当前大部分开发者干的事情吧?求证!使用静态库不仅可以提高开发效率还能隐藏自定义控件的源代码。
下面以将一个实现了可选框的控件制作成静态库的例子来展示控件的封装。
需求分析:1.一个可选的UIButton,后面带有文字提示,比如“确认”.2.当用户点击‘确认’前面的可选框时,可选框变为选中状态。3.当用户再次点击时,可选框变为未选中状态.4.可选框的选中状态与未选中状态分别用两张图片来显示.实际效果如下图:
好了,现在开始制作我们自己的静态库。
首先建立一个“ Cocoa Touch Static Library”工程,命名为“MU_CheckButton”。如下图:
在生成的MU_CheckButton.h文件中,添加头文件:#import <UIKit/UIKit.h>因为我们的MU_CheckButton继承自UIControl。
然后在MU_CheckButton.h中添加MU_CheckButton这个函数库需要实现的功能(即各个函数)。MU_CheckButton.h如下:
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
typedef enum {
CheckButtonStyleDefault = 0,
CheckButtonStyleBox = 1,
} CheckButtonStyle;
@interface MU_CheckButton: UIControl
{
NSString *checkname,*uncheckname;//勾选/反选时的图片文件名
BOOL checked;
NSInteger gap;//文字与可选框之间的间隙
}
@property (retain,nonatomic)id value;//MU_CheckButton的tag
@property (retain,nonatomic)UILabel* label;
@property (retain,nonatomic)UIImageView* icon;
@property (assign,nonatomic)CheckButtonStyle style;//MU_CheckButton的类型,一种有复选框,一种没有
@property (assign,getter = checked,setter = setChecked:)BOOL checked;
@property (assign,getter = gap,setter = setGap:) NSInteger gap;
-(CheckButtonStyle)style;
-(void)setStyle:(CheckButtonStyle)st;
-(void)resizeFrameToRect:(CGRect)rect;//重设控件的位置
@end
在.m文件中实现控件需要的功能。
#import "MU_CheckButton.h"
@implementation MU_CheckButton
@synthesize label,icon,value;
@synthesize style;
-(id)initWithFrame:(CGRect)frame
{
if (self=[super initWithFrame:frame]) {
[self setStyle:CheckButtonStyleDefault];//设置为默认风格
gap=8;
icon=[[UIImageView alloc]initWithFrame:
CGRectMake(0, 0, frame.size.height, frame.size.height)];
[self addSubview:icon];
label=[[UILabel alloc]initWithFrame:CGRectMake(icon.frame.size.width+gap, 0,
frame.size.width-icon.frame.size.width-gap,
frame.size.height)];
label.backgroundColor=[UIColor clearColor];
label.font=[UIFont systemFontOfSize:15];
label.textColor=[UIColor blackColor];
[self addSubview:label];
[self addTarget:self action:@selector(clicked) forControlEvents:UIControlEventTouchUpInside];
label.textAlignment=UITextAlignmentLeft;
checked=NO;//默认不被选中
}
return self;
}
-(CheckButtonStyle)style{
return style;
}
-(void)setStyle:(CheckButtonStyle)st{
style=st;
switch (style) {
case CheckButtonStyleBox:
checkname=@"checked.png";
uncheckname=@"unchecked.png";
break;
default:
break;
}
[self setChecked:checked];
}
-(BOOL)checked{
return checked;
}
-(void)setChecked:(BOOL)b{
checked=b;
if (checked) {
[ icon setImage :[ UIImage imageNamed : checkname ]];
}else {
[ icon setImage :[ UIImage imageNamed : uncheckname ]];
}
}
-(void)clicked
{
[ self setChecked :! checked ];
}
-(void)resizeFrameToRect:(CGRect)rect{
self.frame=rect;
icon.frame=CGRectMake(icon.frame.origin.x,
icon.frame.origin.y,
rect.size.height,
rect.size.height);
label.frame=CGRectMake(label.frame.origin.x+gap,
label.frame.origin.y,
rect.size.width-rect.size.height-gap,
rect.size.height);
}
-(NSInteger)gap
{
return gap;
}
-(void)setGap:(NSInteger)_gap
{
gap=_gap;
}
@end
完成了.m文件的代码编写之后,cmd+B编译我们的静态库。然后,在products下选择libMU_CheckButton.a,右键->show in Finder,找到它。但是默认找到的是Debug-iphoneos下的libMU_CheckButton.a,这个是给真机调试时使用的,它基于基于arm6 arm7编译出来的库文件。如下图:
我们应该用下面那个文件夹debug-iphonesimulator里的.a文件,因为这才是给模拟器用的,它是基于i386(mac就是基于i386的)编译出来的文件,也就是在mac上用的。 (但其实,我们需要的是一个既可以给真机又可以给模拟器使用的.a,这个可参考:http://hi.baidu.com/yunhuaikong/item/6acbbbc8763f40d397445228。)
下面该是使用这个静态库的时候了。
=======================================
再新建一个工程在里面调用我们生成的静态库。新建一个“singalView Application”工程,命名为“MU_CheckButtonDemo”,向其中拖入之前的.a文件(注意是模拟器用的那个)和MU_CheckButton.h。
MU_CheckButtonDemo.m的实现如下:
#import "ViewController.h"
#import "MU_CheckButton.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view setBackgroundColor:[UIColor grayColor]];
MU_CheckButton *checkButton=[[MU_CheckButton alloc]initWithFrame:CGRectMake ( 20 , 60 , 260 , 32 )];
// checkButton.gap=100;//@设置间隙
checkButton. label . text = @"确认" ;
checkButton.label.font=[UIFont systemFontOfSize:20];
checkButton. value =[[ NSNumber alloc ] initWithInt : 1 ];//设置tag value
// 设置按钮的格式
checkButton. style = CheckButtonStyleBox ;
// [checkButton resizeFrameToRect:CGRectMake(0, 20, 100, 30)];//调整大小
// 加入视图
[ self.view addSubview :checkButton];
}
有关静态库的其他问题,可参考:
http://www.cnblogs.com/lovecode/archive/2012/02/11/2346389.html。本文在编写的过程中参考了:
http://blog.csdn.net/dongfengsun/article/details/4840224以及
http://blog.csdn.net/kmyhy/article/details/6197096。
这里特别感谢kmyhy对我问题的回答。