iOS 開發實戰技巧

iOS開發過程中,各種小問題,小技巧。持續更新......

  • 返回輸入鍵盤
<UITextFieldDelegate> 

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [textField resignFirstResponder];
    return YES;
}
  • CGRect
CGRectFromString(<#NSString *string#>)//有字符串恢復出矩形
CGRectInset(<#CGRect rect#>, <#CGFloat dx#>, <#CGFloat dy#>)//創建較小或者較大的矩形
CGRectIntersectsRect(<#CGRect rect1#>, <#CGRect rect2#>)//判斷兩巨星是否交叉,是否重疊
CGRectZero//高度和寬度為零的,位于(0,0)的矩形常量
  • 隱藏狀態欄
[UIApplication sharedApplication] setStatusBarHidden:<#(BOOL)#> withAnimation:<#(UIStatusBarAnimation)#>//隱藏狀態欄
  • 自動適應父視圖大小
self.view.autoresizesSubviews = YES;
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  • UITableView的一些方法
這里我自己做了個測試,縮進級別設置為行號,row越大,縮進越多
<UITableViewDelegate>

- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSInteger row = indexPath.row;
    return row;
}

  • 把plist文件中的數據賦給數組
NSString *path = [[NSBundle mainBundle] pathForResource:@"States" ofType:@"plist"];
NSArray *array = [NSArray arrayWithContentsOfFile:path];
  • 獲取觸摸的點
- (CGPoint)locationInView:(UIView *)view;
- (CGPoint)previousLocationInView:(UIView *)view;

  • 獲取觸摸的屬性
@property(nonatomic,readonly) NSTimeInterval      timestamp;
@property(nonatomic,readonly) UITouchPhase        phase;
@property(nonatomic,readonly) NSUInteger          tapCount;

  • 從plist中獲取數據賦給字典
NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"book" ofType:@"plist"];
NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath];

  • NSUserDefaults注意事項
設置完了以后如果存儲的東西比較重要的話,一定要同步一下
[[NSUserDefaults standardUserDefaults] synchronize];

  • 獲取Documents目錄
NSString *documentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];

  • 獲取tmp目錄
NSString *tmpPath = NSTemporaryDirectory();

  • 利用Safari打開一個鏈接
NSURL *url = [NSURL URLWithString:@"http://baidu.com"];
[[UIApplication sharedApplication] openURL:url];
  • 利用UIWebView顯示pdf文件,網頁等等
<UIWebViewDelegate>

UIWebView *webView = [[UIWebView alloc]initWithFrame:self.view.bounds];
webView.delegate = self;
webView.scalesPageToFit = YES;
webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[webView setAllowsInlineMediaPlayback:YES];
[self.view addSubview:webView];
    
NSString *pdfPath = [[NSBundle mainBundle] pathForResource:@"book" ofType:@"pdf"];
NSURL *url = [NSURL fileURLWithPath:pdfPath];
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:(NSURLRequestUseProtocolCachePolicy) timeoutInterval:5];
[webView loadRequest:request];
  • UIWebView和html的簡單交互
myWebView = [[UIWebView alloc]initWithFrame:self.view.bounds];
[myWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];
NSError *error;
NSString *errorString = [NSString stringWithFormat:@"<html><center><font size=+5 color='red'>AnError Occurred;<br>%@</font></center></html>",error];
[myWebView loadHTMLString:errorString baseURL:nil];

//頁面跳轉了以后,停止載入
-(void)viewWillDisappear:(BOOL)animated {
    if (myWebView.isLoading) {
        [myWebView stopLoading];
    }
    myWebView.delegate = nil;
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}

  • 漢字轉碼
NSString *oriString = @"\u67aa\u738b";
NSString *escapedString = [oriString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

  • 處理鍵盤通知
先注冊通知,然后實現具體當鍵盤彈出來要做什么,鍵盤收起來要做什么
- (void)registerForKeyboardNotifications {
    keyboardShown = NO;//標記當前鍵盤是沒有顯示的
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasHidden:) name:UIKeyboardDidHideNotification object:nil];
}
//鍵盤顯示要做什么
- (void)keyboardWasShown:(NSNotification *)notification {
    if (keyboardShown) {
        return;
    }
    NSDictionary *info = [notification userInfo];
    
    NSValue *aValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];
    CGSize keyboardSize = [aValue CGRectValue].size;
    CGRect viewFrame = scrollView.frame;
    viewFrame.size.height = keyboardSize.height;
    
    CGRect textFieldRect = activeField.frame;
    [scrollView scrollRectToVisible:textFieldRect animated:YES];
    keyboardShown = YES;
}

- (void)keyboardWasHidden:(NSNotification *)notification {
    NSDictionary *info = [notification userInfo];
    NSValue *aValue = [info objectForKey:UIKeyboardFrameEndUserInfoKey];
    CGSize keyboardSize = [aValue CGRectValue].size;
    
    CGRect viewFrame = scrollView.frame;
    viewFrame.size.height += keyboardSize.height;
    scrollView.frame = viewFrame;
    
    keyboardShown = NO;
}
  • 點擊鍵盤的next按鈕,在不同的textField之間換行
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    
    if ([textField returnKeyType] != UIReturnKeyDone) {
        NSInteger nextTag = [textField tag] + 1;
        UIView *nextTextField = [self.tableView viewWithTag:nextTag];
        [nextTextField becomeFirstResponder];
    }else {
        [textField resignFirstResponder];
    }
    
    return YES;
}

  • 設置日期格式
dateFormatter = [[NSDateFormatter alloc]init];
dateFormatter.locale = [NSLocale currentLocale];
dateFormatter.calendar = [NSCalendar autoupdatingCurrentCalendar];
dateFormatter.timeZone = [NSTimeZone defaultTimeZone];
dateFormatter.dateStyle = NSDateFormatterShortStyle;
NSLog(@"%@",[dateFormatter stringFromDate:[NSDate date]]);
  • 加載大量圖片的時候,可以使用
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"icon" ofType:@"png"];
UIImage *myImage = [UIImage imageWithContentsOfFile:imagePath];
  • 有時候在iPhone游戲中,既要播放背景音樂,同時又要播放比如槍的開火音效。
NSString *musicFilePath = [[NSBundle mainBundle] pathForResource:@"xx" ofType:@"wav"];
NSURL *musicURL = [NSURL fileURLWithPath:musicFilePath];
AVAudioPlayer *musicPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:musicURL error:nil];
[musicPlayer prepareToPlay];
musicPlayer.volume = 1;
musicPlayer.numberOfLoops = -1;//-1表示一直循環
  • 從通訊錄中讀取電話號碼,去掉數字之間的-
NSString *originalString = @"(123)123123abc";
NSMutableString *strippedString = [NSMutableString stringWithCapacity:originalString.length];
NSScanner *scanner = [NSScanner scannerWithString:originalString];
NSCharacterSet *numbers = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];

    while ([scanner isAtEnd] == NO) {
        NSString *buffer;
        if ([scanner scanCharactersFromSet:numbers intoString:&buffer]) {
            [strippedString appendString:buffer];
        }else {
            scanner.scanLocation = [scanner scanLocation] + 1;
        }
    }
    NSLog(@"%@",strippedString);
  • 正則判斷:字符串只包含字母和數字
NSString *myString = @"Letter1234";
NSString *regex = @"[a-z][A-Z][0-9]";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];

    if ([predicate evaluateWithObject:myString]) {
        //implement
    }
  • 使用NSURLConnection下載數據
1. 創建對象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]];
[NSURLConnection connectionWithRequest:request delegate:self];

2. NSURLConnection delegate 委托方法
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {

}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    
}

3. 實現委托方法
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    self.receiveData.length = 0;//先清空數據
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [self.receiveData appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    //錯誤處理
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    NSString *returnString = [[NSString alloc]initWithData:self.receiveData encoding:NSUTF8StringEncoding];
    firstTimeDownloaded = YES;
}
  • 隱藏狀態欄
[UIApplication sharedApplication].statusBarHidden = YES;

  • 調用電話,短信,郵件
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"mailto:apple@mac.com?Subject=hello"]];
sms://調用短信
tel://調用電話
itms://打開MobileStore.app
  • 獲取版本信息
UIDevice *myDevice = [UIDevice currentDevice];
NSString *systemVersion = myDevice.systemVersion;

  • NSNotificationCenter帶參數發送
MPMoviePlayerController *theMovie = [[MPMoviePlayerController alloc]initWithContentURL:[NSURL fileURLWithPath:moviePath]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myMovieFinishedCallback:) name:MPMoviePlayerPlaybackDidFinishNotification object:theMovie];
[theMovie play];

- (void)myMovieFinishedCallback:(NSNotification *)aNotification {
    MPMoviePlayerController *theMovie = [aNotification object];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:theMovie];
}

  • 延遲一段時間執行某個函數
// (1) 調用NSObject的方法
[self performSelector:@selector(run) withObject:self afterDelay:2.0];
// 2秒后再調用self的run方法

// (2) 使用GCD函數
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

    // 2秒后異步執行這里的代碼...

});

  • 用NSDateFormatter調整時間格式代碼
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
NSString *currentDateStr = [dateFormatter stringFromDate:[NSDate date]];

  • UIView設置成圓角的方法以及剪切多余部分
mainView.layer.cornerRadius = 6;
mainView.layer.masksToBounds = YES;

  • iPhone 更改鍵盤右下角按鍵的 type
SearchBar *mySearchBar = [[UISearchBar alloc]init];
mySearchBar.frame = CGRectMake(0, 0, self.view.bounds.size.width, 44);
mySearchBar.placeholder = @"placeholderString";
mySearchBar.delegate = self;
[self.view addSubview:mySearchBar];
UITextField *searchField = [[mySearchBar subviews] lastObject];
searchField.returnKeyType = UIReturnKeyDone;
  • tableView左滑出多個按鈕
- (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //刪除按鈕
    UITableViewRowAction *deleteRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"刪除" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath){
        [_dataArray removeObjectAtIndex:indexPath.row];
        [tableView deleteRowsAtIndexPaths:@[indexPath]withRowAnimation:UITableViewRowAnimationAutomatic];
    }];
     
 
    //置頂按鈕
    UITableViewRowAction *toTopRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"置頂" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath){
         
        NSLog(@"置頂");
         
    }];
    toTopRowAction.backgroundColor = [UIColor orangeColor];
     
    //其他按鈕
    UITableViewRowAction *otherRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"其他" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath){
        NSLog(@"其他");
    }];
 
    otherRowAction.backgroundColor = [UIColor lightGrayColor];
 
    //返回按鈕數組
    return @[deleteRowAction, toTopRowAction, otherRowAction];
}

  • 給圖片增加模糊效果
//加模糊效果,image是圖片,blur是模糊度
+ (UIImage *)blurryImage:(UIImage *)image withBlurLevel:(CGFloat)blur {
    //模糊度,
    if ((blur < 0.1f) || (blur > 2.0f)) {
        blur = 0.1f;
    }
     
    //boxSize必須大于0
    int boxSize = (int)(blur * 100);
    boxSize -= (boxSize % 2) + 1;
    NSLog(@"boxSize:%i",boxSize);
    //圖像處理
    CGImageRef img = image.CGImage;
     
    //圖像緩存,輸入緩存,輸出緩存
    vImage_Buffer inBuffer, outBuffer;
    vImage_Error error;
    //像素緩存
    void *pixelBuffer;
     
    //數據源提供者,Defines an opaque type that supplies Quartz with data.
    CGDataProviderRef inProvider = CGImageGetDataProvider(img);
    // provider’s data.
    CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);
     
    //寬,高,字節/行,data
    inBuffer.width = CGImageGetWidth(img);
    inBuffer.height = CGImageGetHeight(img);
    inBuffer.rowBytes = CGImageGetBytesPerRow(img);
    inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData);
     
    //像數緩存,字節行*圖片高
    pixelBuffer = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));
     
    outBuffer.data = pixelBuffer;
    outBuffer.width = CGImageGetWidth(img);
    outBuffer.height = CGImageGetHeight(img);
    outBuffer.rowBytes = CGImageGetBytesPerRow(img);
     
     
    // 第三個中間的緩存區,抗鋸齒的效果
    void *pixelBuffer2 = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));
    vImage_Buffer outBuffer2;
    outBuffer2.data = pixelBuffer2;
    outBuffer2.width = CGImageGetWidth(img);
    outBuffer2.height = CGImageGetHeight(img);
    outBuffer2.rowBytes = CGImageGetBytesPerRow(img);
     
    //Convolves a region of interest within an ARGB8888 source image by an implicit M x N kernel that has the effect of a box filter.
    error = vImageBoxConvolve_ARGB8888(&inBuffer;, &outBuffer2;, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);
    error = vImageBoxConvolve_ARGB8888(&outBuffer2;, &inBuffer;, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);
    error = vImageBoxConvolve_ARGB8888(&inBuffer;, &outBuffer;, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);
     
     
    if (error) {
        NSLog(@"error from convolution %ld", error);
    }
     
    //    NSLog(@"字節組成部分:%zu",CGImageGetBitsPerComponent(img));
    //顏色空間DeviceRGB
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    //用圖片創建上下文,CGImageGetBitsPerComponent(img),7,8
    CGContextRef ctx = CGBitmapContextCreate(
                                             outBuffer.data,
                                             outBuffer.width,
                                             outBuffer.height,
                                             8,
                                             outBuffer.rowBytes,
                                             colorSpace,
                                             CGImageGetBitmapInfo(image.CGImage));
     
    //根據上下文,處理過的圖片,重新組件
    CGImageRef imageRef = CGBitmapContextCreateImage (ctx);
    UIImage *returnImage = [UIImage imageWithCGImage:imageRef];
     
    //clean up
    CGContextRelease(ctx);
    CGColorSpaceRelease(colorSpace);
     
    free(pixelBuffer);
    free(pixelBuffer2);
    CFRelease(inBitmapData);
    CGImageRelease(imageRef);
     
    return returnImage;
}
  • 網易新聞頭部滾動切換
- (void)titleButtonDidClick:(UIButton *)titleButton
{
    self.mainScrollView.contentOffset  = CGPointMake(kScreenWidth * titleButton.tag, 0);
    [UIView animateWithDuration:0.5 animations:^{
        if (self.titleScrollView.contentOffset.x >= 0) {
    self.titleScrollView.contentOffset = CGPointMake(titleButton.x - 150, 0);
        }
        // 先改變contentOffset,若偏移則修正
        if (self.titleScrollView.contentOffset.x <= 0) {
    self.titleScrollView.contentOffset = CGPointZero;
        }
        if (self.titleScrollView.contentOffset.x >= 2 * 900 - kScreenWidth) {
    self.titleScrollView.contentOffset = CGPointMake(2 * 900 - kScreenWidth, 0);
        }
    }];
}
  • 七牛上傳圖片的簡單封裝
#import "QiNiuTool.h"
#import "JKRAccountTool.h"
#import "JKRAccount.h"
#import "QiniuSDK.h"
#import "QiNiuUpLoadResult.h"
#import <UIKit/UIKit.h>
 
@implementation QiNiuTool
 
+ (void)uploadImages:(NSArray *)images complete:(void (^)(NSDictionary *))complete
{
    QNUploadManager *qnm = [[QNUploadManager alloc] init];
    NSDateFormatter *mattter = [[NSDateFormatter alloc]init];
    [mattter setDateFormat:@"yyyyMMddHHmmss"];
    NSString *Nowdate = [mattter stringFromDate:[NSDate date]];
     
    QiNiuUpLoadResult *result = [[QiNiuUpLoadResult alloc] init];
     
    __block int count = 0;
     
    for (int i = 0; i < images.count; i++) {
         
        UIImage *image = images[i];
         
        NSData *uploadData = UIImageJPEGRepresentation(image, 1);
         
        //這里對大圖片做了壓縮,不需要的話下面直接傳uploadData就好
        NSData *cutdownData = nil;
        if (uploadData.length < 9999) {
            cutdownData = UIImageJPEGRepresentation(image, 1.0);
        } else if (uploadData.length < 99999) {
            cutdownData = UIImageJPEGRepresentation(image, 0.6);
        } else {
            cutdownData = UIImageJPEGRepresentation(image, 0.3);
        }
         
        //[JKRAccountTool getAccount].token:token
        [qnm putData:cutdownData key:[NSString stringWithFormat:@"%@%d", Nowdate, i+1] token:[JKRAccountTool getAccount].token complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) {
             
            count++;
             
            NSString *resultKey = [NSString stringWithFormat:@"%d",i];
             
            result.keys[resultKey] = [resp objectForKey:@"key"];
             
            if (count == images.count) {
                complete(result.keys);
            }
             
        } option:nil];
         
    }
     
}
 
@end
  • 導航條漸隱漸現
[_tableView addObserver: self forKeyPath: @"contentOffset" options: NSKeyValueObservingOptionNew context:nil];
 
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
    CGFloat offset=_tableView.contentOffset.y;
    NSLog(@"offset:%f",offset);//越來越大  想要實現效果:一開始全顯示,后來顏色變淺
    CGFloat delta=1-offset/100.f;
    delta=MIN(1,delta);
    NSLog(@"%f",delta);
    self.navigationController.navigationBar.alpha=MIN(1,delta);
 
}
  • 圖片壓縮
用法:UIImage *yourImage= [self imageWithImageSimple:image scaledToSize:CGSizeMake(210.0, 210.0)];
//壓縮圖片
- (UIImage*)imageWithImageSimple:(UIImage*)image scaledToSize:(CGSize)newSize
{
// Create a graphics image context
UIGraphicsBeginImageContext(newSize);
// Tell the old image to draw in this newcontext, with the desired
// new size
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
// Get the new image from the context
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
// End the context
UIGraphicsEndImageContext();
// Return the new image.
return newImage;
}
  • 圖片裁剪,類似新浪微博小圖顯示效果
CGSize asize = CGSizeMake(300, 300);
    UIImage *newimage;
    UIImage *image = [UIImage imageNamed:@""];
    if (nil == image) {
        newimage = nil;
    }
    else{
        CGSize oldsize = image.size;
        CGRect rect;
        if (asize.width/asize.height > oldsize.width/oldsize.height) {
            rect.size.width = asize.width;
            rect.size.height = asize.width*oldsize.height/oldsize.width;
            rect.origin.x = 0;
            rect.origin.y = (asize.height - rect.size.height)/2;
        }
        else{
            rect.size.width = asize.height*oldsize.width/oldsize.height;
            rect.size.height = asize.height;
            rect.origin.x = (asize.width - rect.size.width)/2;
            rect.origin.y = 0;
        }
        UIGraphicsBeginImageContext(asize);
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextClipToRect(context, CGRectMake(0, 0, asize.width, asize.height));
        CGContextSetFillColorWithColor(context, [[UIColor clearColor] CGColor]);
        UIRectFill(CGRectMake(0, 0, asize.width, asize.height));//clear background
        [image drawInRect:rect];
        newimage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }
     
    UIImageView * imgView = [[UIImageView alloc]initWithFrame:CGRectMake(10, 10, 100, 100)];
    imgView.image = newimage;
    [self.view addSubview:imgView];

  • 把時間戳轉換為時間
+ (NSDate *)dateWithTimeIntervalInMilliSecondSince1970:(double)timeIntervalInMilliSecond {
    NSDate *ret = nil;
    double timeInterval = timeIntervalInMilliSecond;
    // judge if the argument is in secconds(for former data structure).
    if(timeIntervalInMilliSecond > 140000000000) {
        timeInterval = timeIntervalInMilliSecond / 1000;
    }
    ret = [NSDate dateWithTimeIntervalSince1970:timeInterval];
     
    return ret;
}
  • 自定義cell中獲取不到cell實際大小的辦法
-(void)drawRect:(CGRect)rect {
    // 重寫此方法,并在此方法中獲取
    CGFloat width = self.frame.size.width;
}

  • 長按圖標抖動
-(void)longPress:(UILongPressGestureRecognizer*)longPress
{
    if (longPress.state==UIGestureRecognizerStateBegan) {
        CAKeyframeAnimation* anim=[CAKeyframeAnimation animation];
        anim.keyPath=@"transform.rotation";
        anim.values=@[@(angelToRandian(-7)),@(angelToRandian(7)),@(angelToRandian(-7))];
        anim.repeatCount=MAXFLOAT;
        anim.duration=0.2;
        [self.imageView.layer addAnimation:anim forKey:nil];
        self.btn.hidden=NO;
    }
}
  • 阿拉伯數字轉化為漢語數字
+(NSString *)translation:(NSString *)arebic

{   NSString *str = arebic;
    NSArray *arabic_numerals = @[@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"0"];
    NSArray *chinese_numerals = @[@"一",@"二",@"三",@"四",@"五",@"六",@"七",@"八",@"九",@"零"];
    NSArray *digits = @[@"個",@"十",@"百",@"千",@"萬",@"十",@"百",@"千",@"億",@"十",@"百",@"千",@"兆"];
    NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:chinese_numerals forKeys:arabic_numerals];
    
    NSMutableArray *sums = [NSMutableArray array];
    for (int i = 0; i < str.length; i ++) {
        NSString *substr = [str substringWithRange:NSMakeRange(i, 1)];
        NSString *a = [dictionary objectForKey:substr];
        NSString *b = digits[str.length -i-1];
        NSString *sum = [a stringByAppendingString:b];
        if ([a isEqualToString:chinese_numerals[9]])
        {
            if([b isEqualToString:digits[4]] || [b isEqualToString:digits[8]])
            {
                sum = b;
                if ([[sums lastObject] isEqualToString:chinese_numerals[9]])
                {
                    [sums removeLastObject];
                }
            }else
            {
                sum = chinese_numerals[9];
            }
            
            if ([[sums lastObject] isEqualToString:sum])
            {
                continue;
            }
        }
        
        [sums addObject:sum];
    }
    
    NSString *sumStr = [sums  componentsJoinedByString:@""];
    NSString *chinese = [sumStr substringToIndex:sumStr.length-1];
    NSString *str1 = [[NSString alloc] init];
    NSString *str2 = [[NSString alloc] init];

    //將億萬替換成億
    if([chinese rangeOfString:@"億萬"].location !=NSNotFound)
    {
        str1 = [chinese stringByReplacingOccurrencesOfString:@"億萬" withString:@"億"];
    }
    else{
        str1 = chinese;
    }
    
    //如果開頭以一十開頭則替換成十
    if ( [str1 hasPrefix:@"一十"]) {
        str2 = [str1 stringByReplacingOccurrencesOfString:@"一十" withString:@"十"];
    }
    else{
        str2 = str1;
    }
    NSLog(@"%@",str);
    NSLog(@"%@",str2);
    return str2;
}
  • 兩種方法刪除NSUserDefaults所有記錄
//方法一
NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
 
//方法二
- (void)resetDefaults {
    NSUserDefaults * defs = [NSUserDefaults standardUserDefaults];
    NSDictionary * dict = [defs dictionaryRepresentation];
    for (id key in dict) {
        [defs removeObjectForKey:key];
    }
    [defs synchronize];
}
  • 截屏 全圖
- (UIImage *)imageFromView: (UIView *) theView
{
     
    UIGraphicsBeginImageContext(theView.frame.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [theView.layer renderInContext:context];
    UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
     
    return theImage;
}
  • 判斷是否用戶開啟了定位服務
if ([CLLocationManager locationServicesEnabled] &&  
                ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized  
                || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined)) {  
                //定位功能可用,開始定位  
                _locationManger = [[CLLocationManager alloc] init];  
                locationManger.delegate = self;  
                [locationManger startUpdatingLocation];  
            }  
            else if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied){  
        NSlog("定位功能不可用,提示用戶或忽略");   
            }
  • 圖片旋轉
UIImage * image = [UIImage imageNamed:@"iphone.png"];
NSData * tempData;
if (UIImagePNGRepresentation(image)) {
    tempData = UIImagePNGRepresentation(image);
    NSLog(@"%@",tempData);
}
else{
    tempData = UIImageJPEGRepresentation(image, 1);
}
CIImage * iImg = [CIImage imageWithData:tempData];
UIImage * tImg = [UIImage imageWithCIImage:iImg scale:1 orientation:UIImageOrientationRight];
NSLog(@"%@",UIImagePNGRepresentation(tImg));
UIImageView * imageView = [[UIImageView alloc]initWithFrame:CGRectMake(10, 200, 200, 80)];
imageView.image = tImg;
[self.view addSubview:imageView];
  • 去除UIImageView鋸齒
imageView.layer.shouldRasterize = YES;
  • 判斷兩個日期之間的間隔
NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyyMMddHHmmss"];
NSDate* toDate     = [dateFormatter dateFromString:@"19700608142033"];
NSDate*  startDate    = [ [ NSDate alloc] init ];
NSCalendar* chineseClendar = [ [ NSCalendar alloc ] initWithCalendarIdentifier:NSGregorianCalendar ];
NSUInteger unitFlags = NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit;
 
NSDateComponents *cps = [ chineseClendar components:unitFlags fromDate:startDate  toDate:toDate  options:0];
 
NSInteger diffYear = [cps year];
NSInteger diffMon = [cps month];
NSInteger diffDay = [cps day];
NSInteger diffHour = [cps hour];
NSInteger diffMin = [cps minute];
NSInteger diffSec = [cps second];
 
NSLog(@" From Now to %@, diff: Years: %d  Months: %d, Days; %d, Hours: %d, Mins:%d, sec:%d", [toDate description], diffYear, diffMon, diffDay, diffHour, diffMin,diffSec );
  • 類似微信發送視頻的流程
//獲取視頻的本地url或者path,對視頻進行獲取第一幀圖片,然后初始化消息的Model,設置封面

NSString *mediaType = [editingInfo objectForKey: UIImagePickerControllerMediaType];
                NSString *videoPath;
                NSURL *videoUrl;
                if (CFStringCompare ((__bridge CFStringRef) mediaType, kUTTypeMovie, 0) == kCFCompareEqualTo) {
                    videoUrl = (NSURL*)[editingInfo objectForKey:UIImagePickerControllerMediaURL];
                    videoPath = [videoUrl path];
                     
                    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoUrl options:nil];
                    NSParameterAssert(asset);
                    AVAssetImageGenerator *assetImageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
                    assetImageGenerator.appliesPreferredTrackTransform = YES;
                    assetImageGenerator.apertureMode = AVAssetImageGeneratorApertureModeEncodedPixels;
                     
                    CGImageRef thumbnailImageRef = NULL;
                    CFTimeInterval thumbnailImageTime = 0;
                    NSError *thumbnailImageGenerationError = nil;
                    thumbnailImageRef = [assetImageGenerator copyCGImageAtTime:CMTimeMake(thumbnailImageTime, 60) actualTime:NULL error:&thumbnailImageGenerationError;];
                     
                    if (!thumbnailImageRef)
                        NSLog(@"thumbnailImageGenerationError %@", thumbnailImageGenerationError);
                     
                    UIImage *thumbnailImage = thumbnailImageRef ? [[UIImage alloc] initWithCGImage:thumbnailImageRef] : nil;
                     
                    XHMessage *videoMessage = [[XHMessage alloc] initWithVideoConverPhoto:thumbnailImage videoPath:videoPath videoUrl:nil sender:@"Jack" timestamp:[NSDate date]];
                    [weakSelf addMessage:videoMessage];
                }
  • 刷新某行cell的方法
//有時候只需要刷新某行的cell的數據,完全沒必要調用[tableView reloadData]刷新整個列表的數據,調用以下方法即可。

NSIndexPath *indexPath_1=[NSIndexPath indexPathForRow:1 inSection:0];
      NSArray *indexArray=[NSArray  arrayWithObject:indexPath_1];
      [myTableView  reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationAutomatic];

  • 由身份證號碼返回性別
-(NSString *)sexStrFromIdentityCard:(NSString *)numberStr{
    NSString *result = nil;
     
    BOOL isAllNumber = YES;
     
    if([numberStr length]<17)
        return result;
     
    //**截取第17為性別識別符
    NSString *fontNumer = [numberStr substringWithRange:NSMakeRange(16, 1)];
     
    //**檢測是否是數字;
    const char *str = [fontNumer UTF8String];
    const char *p = str;
    while (*p!='\0') {
        if(!(*p>='0'&&*p<='9'))
            isAllNumber = NO;
        p++;
    }
     
    if(!isAllNumber)
        return result;
     
    int sexNumber = [fontNumer integerValue];
    if(sexNumber%2==1)
        result = @"男";
    ///result = @"M";
    else if (sexNumber%2==0)
        result = @"女";
    //result = @"F";
     
    return result;
     
     
}
  • 數組隨機重新排列
+ (NSArray *)getRandomWithPosition:(NSInteger)position positionContent:(id)positionContent array:(NSArray *)baseArray {
    NSMutableArray *resultArray = [NSMutableArray arrayWithCapacity:baseArray.count];
    NSMutableArray *tempBaseArray = [NSMutableArray arrayWithArray:baseArray];
     
    while ([tempBaseArray count]) {
        NSInteger range = [tempBaseArray count];
        id string = [tempBaseArray objectAtIndex:arc4random()%range];
        [resultArray addObject:string];
        [tempBaseArray removeObject:string];
    }
     
    NSUInteger index = [resultArray indexOfObject:positionContent];
    [resultArray exchangeObjectAtIndex:index withObjectAtIndex:position - 1];
     
    return resultArray;
}
  • 利用陀螺儀實現更真實的微信搖一搖動畫
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{    
    //想搖你的手機嘛?就寫在這,然后,然后,沒有然后了
    application.applicationSupportsShakeToEdit=YES;
}
 
-(void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
    if(motion==UIEventSubtypeMotionShake) {
         // 真實一點的搖動動畫
        [self addAnimations];
         // 播放聲音
        AudioServicesPlaySystemSound (soundID); 
    }
}
 
- (void)addAnimations {
    CABasicAnimation *translation = [CABasicAnimation animationWithKeyPath:@"transform"];
    translation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    translation.toValue=[NSValue valueWithCATransform3D:CATransform3DMakeRotation(-M_PI_4, 0, 0, 100)];
    translation.duration = 0.2;
    translation.repeatCount = 2;
    translation.autoreverses = YES;
     
    [shake.layer addAnimation:translation forKey:@"translation"];
}

  • GIF圖片解析
+ (NSMutableArray *)praseGIFDataToImageArray:(NSData *)data;
 {
    NSMutableArray *frames = [[NSMutableArray alloc] init];
    CGImageSourceRef src = CGImageSourceCreateWithData((CFDataRef)data, NULL);
    CGFloat animationTime = 0.f;
    if (src) {
        size_t l = CGImageSourceGetCount(src);
        frames = [NSMutableArray arrayWithCapacity:l];
        for (size_t i = 0; i < l; i++) {
            CGImageRef img = CGImageSourceCreateImageAtIndex(src, i, NULL);
            NSDictionary *properties = (NSDictionary *)CGImageSourceCopyPropertiesAtIndex(src, i, NULL);
            NSDictionary *frameProperties = [properties objectForKey:(NSString *)kCGImagePropertyGIFDictionary];
            NSNumber *delayTime = [frameProperties objectForKey:(NSString *)kCGImagePropertyGIFUnclampedDelayTime];
            animationTime += [delayTime floatValue];
            if (img) {
                [frames addObject:[UIImage imageWithCGImage:img]];
                CGImageRelease(img);
            }
        }
        CFRelease(src);
    }
     return frames;
}
  • 在后臺播放音樂
//1. 在Info.plist中,添加"Required background modes"鍵,其值設置是“App plays audio" 
//2. 在播放器播放音樂的代碼所在處,添加如下兩段代碼(當然,前提是已經添加了AVFoundation框架)

//添加后臺播放代碼:
AVAudioSession *session = [AVAudioSession sharedInstance];    
[session setActive:YES error:nil];    
[session setCategory:AVAudioSessionCategoryPlayback error:nil];   
 
//以及設置app支持接受遠程控制事件代碼。設置app支持接受遠程控制事件,
//其實就是在dock中可以顯示應用程序圖標,同時點擊該圖片時,打開app。
//或者鎖屏時,雙擊home鍵,屏幕上方出現應用程序播放控制按鈕。
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; 
 
 
//用下列代碼播放音樂,測試后臺播放
// 創建播放器  
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];  
[url release];  
[player prepareToPlay];  
[player setVolume:1];  
player.numberOfLoops = -1; //設置音樂播放次數  -1為一直循環  
[player play]; //播放
  • 添加TextFile時,看不到時記得設置boardStyle屬性
UITextField *textField = [[UITextField alloc] init];
textField.frame = CGRectMake(50, 40, 120, 40);
//設置boardStyle屬性
textField.borderStyle = UITextBorderStyleRoundedRect;
[self.view addSubview:textField];
  • 設置tableView的組與組間的頭部高度和尾部高度,可減小組間的間距
  self.tableView.sectionFooterHeight = 10;
  self.tableView.sectionHeaderHeight = 10;
  • 實現tableView組標題不懸浮效果
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (scrollView == self.tableView)
    {
        CGFloat sectionHeaderHeight = 25; //sectionHeaderHeight
        if (scrollView.contentOffset.y <= sectionHeaderHeight&&scrollView.contentOffset.y >= 0) {
            scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
        } else if (scrollView.contentOffset.y >= sectionHeaderHeight) {
            scrollView.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, 0, 0, 0);
        }
    }
}
  • table隱藏多余的空cell
tableView.tableFooterView = [[UIView alloc] init];
  • 有時候想自定義tableView的分區頭/尾,但是自定義分區頭/尾的代理方法不執行,這時候要檢查一下是否實現了返回高度的代理方法以及返回多少分區的代理方法.如果以上方法返回值為零或者不實現程序將不會執行自定義分區頭的方法.

  • 如何快速的查看一段代碼的執行時間。

//有的時候程序執行一段代碼的時候有卡頓現象,想知道到底是哪一行代碼出現的問題,可以這么做:
#define TICK   NSDate *startTime = [NSDate date]
#define TOCK   NSLog(@"Time: %f", -[startTime timeIntervalSinceNow])

//在想要查看執行時間的代碼的地方進行這么處理
TICK
//這里是代碼...
TOCK
  • 開發中如果用到在一個viewController中添加另一個viewController的view,這時候一定要注意把viewController設置全局變量,否則會出現一些稀奇古怪的問題.

  • 自定義了leftBarbuttonItem左滑返回手勢失效了怎么辦?

//解決方法就是在自定義的導航欄的viewDidLoad方法中添加如下代碼
    __weak typeof (self) weakSelf = self;
    //解決因為自定義導航欄按鈕,滑動返回失效的問題
    if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.interactivePopGestureRecognizer.delegate = weakSelf;
    }
  • 另外再教大家一個實用的方法,當Push的多個界面的導航欄返回按鈕相同時,可以在自定義的UINavigationController中重寫Push的方法,攔截Push操作,

并同時設置push后的TabBar隱藏(如果有需要的話),代碼如下:

/**
 *  重寫這個方法目的:能夠攔截所有push進來的控制器
 *
 *  @param viewController 即將push進來的控制器
 */
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
   

    if (self.viewControllers.count > 0) { // 這時push進來的控制器viewController,不是第一個子控制器(不是根控制器)
        /* 自動顯示和隱藏tabbar */
        viewController.hidesBottomBarWhenPushed = YES;
        
        /* 設置導航欄上面的內容 */
        // 設置左邊的返回按鈕
        viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem itemWithTarget:self action:@selector(back) image:@"home_nav_bar_back_icon" highImage:@"home_nav_bar_back_icon"];
         }

    [super pushViewController:viewController animated:animated];
}

- (void)back
{
    // 因為self本來就是一個導航控制器,self.navigationController這里是nil的
    [self popViewControllerAnimated:YES];
}
  • ScrollView莫名其妙不能在viewController劃到頂怎么辦?
self.automaticallyAdjustsScrollViewInsets = NO;
  • 怎么點擊self.view就讓鍵盤收起
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event  
{  
   [self.view endEditing:YES];  
}  
  • 想在代碼里改在xib里添加的layoutAttributes
//像拉Button一樣地拉你的約束,nslayoutattribute也是可以拉線的。
  如果不想拉線的話,可以在這個方法里修改
-(void)viewDidAppear:(BOOL)animated{
    
}

  • 怎么把我的navigationbar弄成透明的而不是帶模糊的效果?
self.navigationBar setBackgroundImage:[UIImage new]  
                         forBarMetrics:UIBarMetricsDefault];  
self.navigationBar.shadowImage = [UIImage new];  
self.navigationBar.translucent = YES;  
  • 怎么改變uitextfield placeholder的顏色和位置?
//繼承uitextfield,重寫這個方法:
- (void) drawPlaceholderInRect:(CGRect)rect {  
    [[UIColor blueColor] setFill];  
    [self.placeholder drawInRect:rect withFont:self.font lineBreakMode:UILineBreakModeTailTruncation alignment:self.textAlignment];  
}  
  • iOS9 HTTP 不能正常使用的解決辦法
1.在Info.plist中添加NSAppTransportSecurity類型Dictionary。
2.在NSAppTransportSecurity下添加NSAllowsArbitraryLoads類型Boolean,值設為YES

以上是在開發中經常用到的一些方法,以供自己查閱以及大家使用,歡迎大家補充.
持續更新中...
更新時間: 2016.6.2

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,963評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,348評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,083評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,706評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,442評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,802評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,795評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,983評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,542評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,287評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,486評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,030評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,710評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,116評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,412評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,224評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,462評論 2 378

推薦閱讀更多精彩內容