ios小技巧

暫時總結出這些,後續會慢慢增加
有點亂,實在是文筆不好,請見諒
九十九條啊,我慢慢積累,一年估計還是能寫到的吧
(一)關於UITableView
1.任意設置Cell選中狀態的背景色:
UIView *bgView = [[UIView alloc] init];
bgView.backgroundColor = [UIColor orangeColor];
self.selectedBackgroundView = bgView;
[bgView release];
該方法設置的是純色, 也可以使用任何圖片,把selectedBackgroundView設成UIImageView

除了上面的方法,前幾天發現了一個新方法:重寫UITableViewCell 的 setSelected:animated:方法
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];


if (selected) {
self.backgroundColor = RGB(224, 152, 40);
}
else {
self.backgroundColor = [UIColor clearColor];
}
}


2.如果Table中有控件,這裏以switch爲例(適合其它可修改值的各種控件),要在switchUIControlEventValueChanged事件的處理方法裏把值記錄下來。以下方法是不可取的:在執行的最後把所有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的drawAtPointdrawInRect方法
 
(五)一個不停震動的方法:
// 定義一個回調函數,震動結束時再次發出震動
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 ? @"包含" : @"不包含"
 
(二十三)沒有用到類的成員變量的,都寫成類方法

(二十四)navigationItembackBarButtonItem的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

(二十六)
改變UIAlertView背景UIAlertView默認是半透明的,會透出背景的內容,有時看着有些混亂。可以寫個改變背景的方法changeBackground。
@interface UIAlertView (changeBK)
- (void)changeBackground;
@end


@implementation UIAlertView (changeBK)
- (void)changeBackground
{
for(UIView * v in [self subviews]){
if ([v isKindOfClass:[UIImageView class]]) {
UIImage *theImage = [UIImage imageNamed:@"AlertView.png"];
((UIImageView*)v).image = theImage;
break;
}
}
}
@end





在[alertView show]之後或willPresentAlertView:中調用即可。
// UIAlertView *alertView = [UIAlertView alloc] init ...
...
[alertView show];
[alertView changeBackground];




(二十七)浮動提示
有時需要顯示一個視圖,幾秒後再消失的功能,這個功能也可以寫成category
@interface UIView (AutoRemove)
- (void)removeAfterDelay:(NSTimeInterval)time;
- (void)removeImediatly;
@end


@implementation UIView (AutoRemove)
- (void)removeAfterDelay:(NSTimeInterval)time
{
[self performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:time];
}


- (void)removeImediatly
{
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(removeFromSuperview) object:nil];
[self removeFromSuperview];
}
@end


(二十八)改變UITextField的背景
可以給textField加好看的邊框等
@interface UITextField (changeBK)
-(void)orangeBackground;
@end


@implementation UITextField (changeBK)
-(void)orangeBackground
{
self.background = [[UIImage imageNamed:@"fieldBK.png"] stretchableImageWithLeftCapWidth:5 topCapHeight:5];
}
@end
發佈了4 篇原創文章 · 獲贊 4 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章