在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對我問題的回答。