[iPhone 開發]美女開發者總結的25條iOS開發經驗

(一)關於UITableView 
1.任意設置Cell選中狀態的背景色: 
UIView *bgView = [[UIView alloc] init]; 
bgView.backgroundColor = [UIColor orangeColor]; 
self.selectedBackgroundView = bgView; 
[bgView release]; 
該方法設置的是純色, 也可以使用任何圖片,把selectedBackgroundView設成UIImageView。 

2.如果Table中有控件,這裏以switch爲例(適合其它可修改值的各種控件),要在switch的UIControlEventValueChanged事件的處理方法裏把值記錄下來。以下方法是不可取的:在執行的最後把所有cell遍歷一遍,處理各控件的值。因爲沒顯示出來的cell,是取不到的,當然也就取不到該cell裏的控件。所以正確的做法是,在控件可見時,如果值變了,立即處理。當然,如果你的Cell少,不會出現隱藏的情況就隨便了。 

3.方法flashScrollIndicators:這個很有用,閃一下滾動條,暗示是否有可滾動的內容。可以在ViewDidAppear或[table reload]之後調用。 

4.點擊Cell中的按鈕時,如何取所在的Cell:
-(void)OnTouchBtnInCell:(UIButton )btn 

CGPoint point = btn.center; 
point = [table convertPoint:point fromView:btn.superview]; 
NSIndexPath
 indexpath = [table indexPathForRowAtPoint:point]; 
UITableViewCell *cell = [table cellForRowAtIndexPath:indexpath]; 
... 
//也可以通過一路取btn的父窗口取到cell,但如果cell下通過好幾層subview纔到btn,就要取好幾次 superview,所以我用上面的方法,比較通用。這種方法也適用於其它控件。 


(二)設置線寬,如果是retina屏,lineWidth設爲1,實際顯示的寬度是2個像素,這裏進行一下處理:

#define SETLINEWIDTH(ctx,w) CGContextSetLineWidth(ctx, w/[UIScreen mainScreen].scale) 

(三)_cmd:表示該方法的selector,可以賦值給SEL類型的變量,可以做爲參數傳遞。 
例如一個顯示消息的方法: 
-(void)ShowNotifyWithString:(NSString *)notifyString fromMethod:(SEL) originalMethod; 
originalMethod就是調用這個方法的selector。 

調用: 
NSString *stmp = @"test"; 
[self ShowNotifyWithString:stmp fromMethod:_cmd]; 

如何記錄當前方法名稱: 
NSLog(NSStringFromSelector(_cmd)); 

(四)在CGContext中輸出漢字:CGContextShowTextAtPoint是不支持漢字的,需要用NSString的drawAtPoint或drawInRect方法 

(五)一個不停震動的方法: 
// 定義一個回調函數,震動結束時再次發出震動 
void MyAudioServicesSystemSoundCompletionProc (SystemSoundID ssID,void clientData) 

BOOL
 iShouldKeepBuzzing = clientData; 
if (*iShouldKeepBuzzing) { AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); 
} else { 
//Unregister, so we don't get called again... 
AudioServicesRemoveSystemSoundCompletion(kSystemSoundID_Vibrate); 
}



以下爲調用的代碼: 
BOOL iShouldKeepBuzzing = YES; 
AudioServicesAddSystemSoundCompletion ( 
kSystemSoundID_Vibrate,

NULL,

NULL,

MyAudioServicesSystemSoundCompletionProc,

&iShouldKeepBuzzing ); 
AudioServicesPlaySystemSound (kSystemSoundID_Vibrate); 

(六)關於更新,iPhone自動保存document中的內容,如果你把文件放在document中,以後開發又改了這個文件的內容或格式,那更新之後運行很可能出錯。解決的辦法是,配置文件放bundle裏,或者改個文件名。每次更新前都要從App store 下載舊版本,運行一段一時間後,再此基礎上編譯新版,運行不出錯才能上傳 

(七)初學者或者不小心容易犯的錯誤:在dealloc裏要調用[super dealloc],千萬不要調用[super release] 
(八)需要調試的類最好重寫description,輸出重要變量的值,因爲調試窗口variableView有時候變量值顯示不出來。 
(九)去掉app圖標的發光效果:info.plist裏增加Icon already includes gloss effects,值設爲YES
(十)寫代碼時字符串太長 怎麼換行:NSString *string = @"ABCDEFGHIJKL" \ 
"MNOPQRSTUVsWXYZ";
(十一)UIImage:stretchableImageWithLeftCapWidth:topCapHeight: 有時圖片模糊(blur)的原因:像素沒有和device pixel對齊.使用instrument 的Core Animation可以檢測這個,勾選"color misaligned images",如果圖片顯示爲紅紫色,就是沒有對齊
(十二)UIPopoverController如果是用presentPopoverFromBarButtonItem顯示的,設備旋轉時,popover可以自動調整位置;如果是用presentPopoverFromRect顯示的, 需要present again 
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 

[aPopover presentPopoverFromRect:targetRect.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; 

(十三)UIColor colorWithRed:green:blue:alpha:這個方法的參數必須用浮點型。 
假如使用Xcode自帶的取顏色的工具,取到的RGB值分別爲:25,25,25, 
傳給上述方法的參數應爲25/255.0或25.0/255。如果用整型25/255,經過取整,小數部分沒有了,顯示出來的顏色和取到的是不一樣的。可以定義一個宏: 
#define RGB(A,B,C) [UIColor colorWithRed:A/255.0 green:B/255.0 blue:C/255.0 alpha:1.0] 
然後用RGB(25,25,25)就可以了 

(十四)禁止textField和textView的複製粘貼菜單: 
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender 

if ([UIMenuController sharedMenuController]) { 
[UIMenuController sharedMenuController].menuVisible = NO; 

return NO; 


(十五)時間相關 
NSDate需要設置calendar,使用不方便也因爲服務器傳過來的是time_t格式,所以我在客戶端對時間的操作主要用的C語言的方法。 
需要注意的是,有的函數不是線程安全的,也就是說在同一個範圍內調用多次時,需要調用線程安全的版本,這樣的函數有: 
localtime_r 
asctime_r 
ctime_r 
gmtime_r 
localtime_r 
另外,可以直接給struct tm各成員變量賦值,例如(注意順序) 
struct tm tmStart = {second,minute,hour,day, mon, year}; 
struct tm的各成員是不能的加減的,因爲超過了各變量的範圍,可能出錯,需要先轉成time_t,再加減相應的時間

(十六) 如果重載loadView,一定要在這個方法裏產生一個self.view。可以調用[super loadView],也可以使用alloc+init。 
錯誤情況舉例:loadView 直接調用self.view.alpha = 0.5; 因爲self.view爲nil,self.view.alpha這句又會調用loadView,也就是loadView不斷調用loadView,進入了死循環 

(十七)GestureRecognizer相關 
1.一個View有GestureRecognizer又有按鈕(或其它需要處理action event的控件)時,有時按鈕不靈敏,解決辦法: 
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch 

CGPoint pt = [touch locationInView:baseView]; 
UIView *btn = [baseView viewWithTag:TAG_MYBTN]; 
CGPoint ptInbtn = [baseView convertPoint:pt toView:btn]; 
return ![btn pointInside:ptInbtn withEvent:nil]; 


2.實現某個view點一下就移除時,要防止移除兩次。(此方法適用於希望GestureRecognizer只執行一次的情況)
-(void)OnTapViewTobeRemoved:(UITapGestureRecognizer *)sender 

if (!sender.enabled) { 
return; 

sender.enabled = NO; 
[sender.view removeFromSuperview]; 


(十八)如何進入軟件在app store 的頁面:
先用iTunes Link Maker找到軟件在訪問地址,格式爲itms-apps://ax.itunes.apple.com/...,然後
#define ITUNESLINK @"itms-apps://ax.itunes.apple.com/..." 
NSURL *url = [NSURL URLWithString:ITUNESLINK]; 
if([[UIApplication sharedApplication] canOpenURL:url]){ 
[[UIApplication sharedApplication] openURL:url]; 

如果把上述地址中itms-apps改爲http就可以在瀏覽器中打開了。可以把這個地址放在自己的網站裏,鏈接到app store。
iTunes Link Maker地址:http://itunes.apple.com/linkmaker

(十九)someview顯示一斷時間後自動消失 
[self performSelector:@selector(dismissView:) withObject:someview afterDelay:2]; 
這麼寫比用NSTimer代碼少,不過哪種都行的,這裏只是提供一種不同的方法
(二十)使提示窗口在任何界面都能顯示: 
[self.navigationController.view addSubview:(自定義的提示窗口)] 
或用UIAlertView 
(二十一)禁止程序運行時自動鎖屏 
[[UIApplication sharedApplication] setIdleTimerDisabled:YES]; 
(二十二)判斷一個字符串是否包含另一個字符串: 
[str1 rangeOfString:str2].length != 0 ? @"包含" : @"不包含" 

(二十三)沒有用到類的成員變量的,都寫成類方法 

(二十四)navigationItem的backBarButtonItem的action是不會執行的.無論怎麼改,除了popViewController什麼都不執行。 
例如: 
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:self action:@selector(onComingback)]; 
self.navigationItem.backBarButtonItem= backButton; 
在下一級視圖中點“返回”,onComingback也是不會執行的。target和action都被忽略了,所以參數用nil就行了 
要想在點“返回”時執行某段代碼,只能自己做一個像返回按鈕那樣的UIBarButtonItem,圖片是需要自己做的。self.navigationItem.leftBarButtonItem= custombackButton; // custombackButton的方法中包含popViewController和你想加的其它代碼 

(二十五)category可以用來調試。除了隱藏私有方法外,我主要用它截住函數。 
例1:測試時我想知道TableViewCell有沒有釋放,就可以這樣寫 
@implementation UITableViewCell(dealloc) 
-(void)dealloc 

NSLog(@"%@",NSStringFromSelector(_cmd)); 
// allSubviews是cookBook裏的函數,可以取一個view的所有subView 
NSArray *array = allSubviews(self); 
NSLog(@"%@",array); 

[super dealloc]; 

@end 
其它的類也可以這樣寫,你隨便輸出什麼 
例2:我調試程序,覺得table的大小變了,想找到在哪改變的,這樣做: 
@implementation UITableView(setframe) 
-(void)setFrame:(CGRect)frame 

NSLog(%"%@",self); 
[super setFrame: frame]; 

@end 



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章