OC常用代码

原创
2014/11/27 11:10
阅读数 84

(一)关于UITableView 

1.任意设置Cell选中状态的背景色: 

UIView *bgView = [[UIView allocinit]; 

bgView.backgroundColor = [UIColor orangeColor]

self.selectedBackgroundView = bgView; 

[bgView release]; 

该方法设置的是纯色, 也可以使用任何图片,把selectedBackgroundView设成UIImageView。 

  

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 permittedArrowDirecti*****: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] 

然后用#191919就可以了 

(十四)禁止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 sharedApplicationcanOpenURL:url]){ 

     [[UIApplication sharedApplicationopenURL: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 sharedApplicationsetIdleTimerDisabled:YES]; 

(二十二)判断一个字符串是否包含另一个字符串: 

[str1 rangeOfString:str2].length != ? @"包含" : @"不包含" 

  

(二十三)没有用到类的成员变量的,都写成类方法 

(二十四)navigationItembackBarButtonItem的action是不会执行的.无论怎么改,除了popViewController什么都不执行。 
例如: 
UIBarButtonItem *backButton = [[UIBarButtonItem allocinitWithTitle:@"返回" 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  

 

通过地点名得到经纬度

方法一 
//
//  MapHelper.m
//  JiaoTong
//
//  Created by MOL on 11-6-17.
//  Copyright 2011 MOL. All rights reserved.
//

#import "MapHelper.h"

#import "JSON.h"

@implementation MapHelper

+ (CLLocationCoordinate2D)getPostion:(NSString *)address
{
    NSString *googleURL = [NSString stringWithFormat:@"http://maps.google.com/maps/api/geocode/json?address=%@&sensor=true",
                           [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

    CLLocationCoordinate2D position;
    position.latitude = 0.0;
    position.longitude = 0.0;

    NSError *error;
    NSString *retstr = [NSString stringWithContentsOfURL:[NSURL URLWithString:googleURL] encoding:NSUTF8StringEncoding error:&error];
    if (retstr)
    {
//        NSLog(@"retstr: %@", retstr);
        NSDictionary *dict = [retstr JSONValue];
        if (dict)
        {
            NSArray *results = [dict objectForKey:@"results"];
            if (results && results.count > 0)
            {
                NSDictionary *geometry = [[results objectAtIndex:0] objectForKey:@"geometry"];
                NSDictionary *location = [geometry objectForKey:@"location"];
                position.latitude = [[location objectForKey:@"lat"] doubleValue];
                position.longitude = [[location objectForKey:@"lng"] doubleValue];                
            }
        }
    }
    else
    {
        NSLog(@"error: %@", error);
    }

    return position;
}

@end

方法二  根据地址查经纬度

NSString*address = @"tokyo";
 
   //查詢經緯度
    NSString*output = @"csv";
    NSString*key = @"YouKey";
    NSString*urlStr = [NSStringstringWithFormat:@"http://maps.google.com/maps/geo?q=%@&output=%@&key=%@",address,output,key];
   
    NSURL *url =[NSURL URLWithString:urlStr];


    NSString*retstr = [NSString stringWithContentsOfURL:urlencoding:NSUTF8StringEncoding error:nil];

    NSArray*resultArray = [retstr componentsSeparatedByString:@","];
   
    doublelatitude = [[resultArray objectAtIndex:2] doubleValue];
    doublelongitude = [[resultArray objectAtIndex:3] doubleValue];

 

1、Xcode调试技巧—在系统抛出异常处设置断点
有时候我们的程序不知道跑到哪个地方就 crash 了,而 crash 又很难重现。
保守的做法是在系统抛出异常之前设置断点,具体来说是在 objc_exception_throw处设置断点。
设置步骤为:首先在 XCode 按 CMD + 6,进入断点管理窗口;
然后点击右下方的 +,增加新的 Symbolic Breakpoint。
在 Symbol 一栏输入:objc_exception_throw,然后点击 done,完成。
这样在 Debug 模式下,如果程序即将抛出异常,就能在抛出异常处中断了。
比如在前面的代码中,我让 [firstObjctcrashTest]; 抛出异常。在 objc_exception_throw 处设置断点之后,程序就能在该代码处中断了,我们从而知道代码在什么地方出问题了。

2、计算UIlabel 随字体多行后的高度
+ (CGFloat)calcTextHeight:(int)textWidth text:(NSString *)text font:(int)fontSize {
    CGRect bounds, result;
    bounds = CGRectMake(0, 0, textWidth, 300);
    
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
    label.font = [UIFont systemFontOfSize:fontSize];
    label.text = text;
    result = [label textRectForBounds:bounds limitedToNumberOfLines:20];
    return result.size.height;
}

或 者CGSize requiredSize = [introduceLabel.text sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(296.0f, FLT_MAX) lineBreakMode:UILineBreakModeTailTruncation];

3、计算当前label随字体增加的长度(单行)
CGSize boundingSize = CGSizeMake(320.0f, CGFLOAT_MAX);
CGSize requiredSize = [status.user.username sizeWithFont:[UIFont boldSystemFontOfSize:13] constrainedToSize:boundingSize lineBreakMode:UILineBreakModeWordWrap];
CGFloat requiredWidth = requiredSize.width;


4、view控件加边框
profileImageButton = [UIButton buttonWithType:UIButtonTypeCustom];
[profileImageButton.layer setMasksToBounds:YES];
[profileImageButton.layer setCornerRadius:4.0]; //设置矩形四个圆角半径
[profileImageButton.layer setBorderWidth:1.0];   //边框宽度
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGColorRef colorref = CGColorCreate(colorSpace,(CGFloat[]){225.0/255.0, 225.0/255.0, 225.0/255.0, 1.0 });
[profileImageButton.layer setBorderColor:colorref];//边框颜色

单独设置圆角
[iconImage.layer setCornerRadius:4.0];
[iconImage setClipsToBounds:YES];

5、时区返回格式为数字(-12—+12)  
-(NSString *)getTimeZone{
    NSString *zone = [[NSTimeZone systemTimeZone] description];//Europe/Berlin//       America/New_York//   Asia/Harbin
                                                                               //这三个可以用来测试exp:NSString *zone = [[NSTimeZone timeZoneWithName:@"America/New_York"] description];
    NSString *time = [[zone componentsSeparatedByString:@"offset "] objectAtIndex:1];
    int inv = [time intValue];
    int result = inv / (60 * 60);
    if (result>0) {
        return [NSString stringWithFormat:@"+%d", result];
    }
    return [NSString stringWithFormat:@"%d", result];
}

6、判定输入框不为空格以及空
   NSString *_textField=[textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    if ([_textField length] == 0) {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"" message:@"评论内容不能为空!" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil];
        [alertView show];
        return NO;
    }


7、根据当前键盘的高度来设置UITextField的位置
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardDidShowNotification object:nil];
}

- (void)keyboardWillShow:(id)sender {
    CGRect keyboardFrame;
    [[[((NSNotification *)sender) userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardFrame];
    CGFloat keyboardHeight = CGRectGetHeight(keyboardFrame);
    [self.textImageView setFrame:CGRectMake(0, 416-keyboardHeight, 320, 45)];
}
8、设置label ,imageview,等点击时事件
    UITapGestureRecognizer *imageTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapImage:)];
   // [imageView setUserInteractionEnabled:YES]; 如果不能点击,设置可编辑
    [imageView addGestureRecognizer:imageTap];

9、判断剩余字数(字母数字符号两个算一个汉字)
-(int)charNumber:(NSString *)strTemp
{
    int strLength =1;
    char *p =(char *) [strTemp cStringUsingEncoding:NSUnicodeStringEncoding];
    for (int i=0; i<[strTemp lengthOfBytesUsingEncoding:NSUnicodeStringEncoding]; i++)
    {
        if (*p) {
            p++;
            strLength++;
        }
        else{
            p++;
        }
    }
    return strLength/2;
}

10、UIWebView加载gif图片  ——这样可以解决gif图片不能下载到本地加载,使用SDWebImage down也出现界面不流畅,卡的问题
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, [homeTableCell getImageWidth:funnyPic], [homeTableCell getImageHeight:funnyPic])];
        webView.backgroundColor = [UIColor clearColor];
       // webView.scalesPageToFit = NO; 这一句我一直没搞清楚,有时对,有时不对的,注释了吧
        //禁止webView的滑动 这样写主要是因为5.0以前的系统不能直接获取到webView.scrollView
        [(UIScrollView *)[[webView subviews] objectAtIndex:0] setBounces:NO];
// 不让有白色的边,这个margin是必须的  
        NSString *html = [NSString stringWithFormat:@"<html><body style=\"margin: 0px;\"><img src=\"%@\"></body></html> ",funnyPic.imageUrl];
        [webView loadHTMLString:html baseURL:nil];
        [imageView addSubview:webView];

11、插入加载更多 tableview reloadData闪的问题
        if (requestArray && [requestArray count] > 0) {
            int cellCount = [requestArray count];//获取一共有几行
            NSMutableArray *indexArray = [[NSMutableArray alloc]initWithCapacity:10];
            int numCountNow = [self.tableView numberOfRowsInSection:0];
            for (; cellCount > 0; cellCount--) {
                NSIndexPath *path = [NSIndexPath indexPathForRow:numCountNow + cellCount - 1 inSection:0];
                [indexArray addObject:path];
            }
            [self.tableView insertRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationNone];
        }

12、Image 加载16进制的 图片(编译成freamwork的时候不能直接加载png图片,要转化)
首先,使用UltraEdit把图片转化为16进制
static const char _playerPause_icon [] = {
    0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52,
    0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1B, 0x08, 0x06, 0x00, 0x00, 0x00, 0x9A, 0xF6, 0x64,
    0x9C, 0x00, 0x00, 0x00, 0x39, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8D, 0x63, 0x64, 0x60, 0x60, 0x38,
    0xC3, 0x80, 0x1D, 0x98, 0x60, 0x11, 0xC3, 0xAA, 0x96, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xB1, 0x4A,
    0x30, 0x32, 0x32, 0xA2, 0x8B, 0xE1, 0x52, 0xCB, 0x84, 0xC3, 0x15, 0x24, 0x81, 0x51, 0x43, 0x46,
    0x0D, 0x19, 0x35, 0x64, 0xD4, 0x90, 0x51, 0x43, 0x46, 0x0D, 0xA1, 0xA7, 0x21, 0x00, 0xDD, 0x84,
    0x09, 0xFD, 0x6B, 0x3C, 0x1F, 0xCB, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42,
    0x60, 0x82
};
然后加载
[playButton setImage:[UIImage imageWithData:[NSData dataWithBytes:_playerPause_icon length:sizeof(_playerPause_icon)/sizeof(char)]] forState:UIControlStateNormal];

13、倒计时(剩余时间)
- (void)timerFireMethod:(NSTimer*)theTimer{
    
    id obj = [theTimer userInfo];
    NSDateFormatter *f1 = [[NSDateFormatter alloc] init];
    [f1 setDateFormat:@"yyyy-MM-dd HH:mm:ss.S"];
    
    NSDate *theDay = [f1 dateFromString:(NSString*)obj];
    [f1 release];

    NSCalendar *cal = [NSCalendar currentCalendar];//定义一个NSCalendar对象
    
    NSDate *today = [NSDate date];//得到当前时间
    
    //用来得到具体的时差
    unsigned int unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
    NSDateComponents *d = [cal components:unitFlags fromDate:today toDate:theDay options:0];
    
    NSString *countdown = [NSString stringWithFormat:@"%d日%d时%d分%d秒", [d month],[d day], [d hour], [d minute], [d second]];
    
    self.timeLabel.text = countdown;
    return ;
    
}

14、九宫格或者其他类型的坐标设置
        frame.size.width = 60;//设置按钮坐标及大小
        frame.size.height = 60;
        frame.origin.x = (i%3)*(60 + 32)+40;
        frame.origin.y = floor(i/3)*(60 + 24)+60;


展开阅读全文
打赏
0
1 收藏
分享
加载中
更多评论
打赏
0 评论
1 收藏
0
分享
返回顶部
顶部