iOS

iOS小技巧总结

转眼也写了好久的iOS了,把工作中的小技巧总结一下

Posted by yasin on October 23, 2015

OC和swift混编

swift调用OC
1、创建一个swift或者oc的工程:我这里是创建的Swift语言的工程,工程名SwiftTest 
2、在工程中代码目录下创建一个oc的类,选择oc语言, 会出一个对话框,选择YES    
3、这时会在工程里看到下图这样一个头文件  *-Bridging-Header.h
4、在这个头文件里添加你的OC文件的.h文件,就可以在任意swift文件中自行调用所包含的oc文件了。 #import “aaa.h”

OC调用swift
在工程的target-》build Setting->package下个性如下两项 
Defines Module 改为YES
Product Module Name的值加上“-swift.h”作为头文件被OC包含

图片拉伸填满

//拉伸填满
+(UIImage *)resizeImageWithImageName:(NSString *)imageName{
    UIImage *image=[self imageNamed:imageName];
    //从中间开始拉伸
    return [image stretchableImageWithLeftCapWidth:image.size.width*0.5 topCapHeight:image.size.height*0.5];
}

改变图片大小

- (UIImage *)scaleToSize:(UIImage *)img size:(CGSize)size{
    UIGraphicsBeginImageContext(size);
    [img drawInRect:CGRectMake(0, 0, size.width, size.height)];
    UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return scaledImage;
}

隐藏状态栏

-(BOOL)prefersStatusBarHidden{
    return YES;
}

跳转时隐藏tabbar

viewController.hidesBottomBarWhenPushed=YES;

Json和NSString转换

//将json对象装换成json字符串
+(NSString *)coverseObj2JsonStrWithObj:(id)obj{
    NSError *error=nil;
    NSData *data=[NSJSONSerialization dataWithJSONObject:obj options:0 error:&error];
    if(!error){
        return [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    }else{
        return nil;
    }
}
//将json字符串转换成json对象
+(id)converseJsonStr2ObjWithJsonStr:(NSString *)jsonStr{
    NSError *error=nil;
    NSData *data=[jsonStr dataUsingEncoding:NSUTF8StringEncoding];
    id obj =[NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
    if(!error){
        return obj;
    }else{
        return nil;
    }
}

改变状态栏的颜色

self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
     /*
     UIBarStyleDefault          = 0,
     UIBarStyleBlack            = 1,
     UIBarStyleBlackOpaque      = 1, // Deprecated. Use UIBarStyleBlack
     UIBarStyleBlackTranslucent = 2
     */

改变导航栏上左右视图的位置

_weatherView=[[WeatherView alloc]initWithFrame:CGRectMake(0, 0, 45, 50)];
    UIBarButtonItem *leftBarButon = [[ UIBarButtonItem alloc ] initWithCustomView :_weatherView];
    if(([[[UIDevice currentDevice] systemVersion] floatValue]>=7.0?20:0)){
        UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
        negativeSpacer.width = -10;//这个数值可以根据情况自由变化
        self.navigationItem.leftBarButtonItems = @[negativeSpacer, leftBarButon];
    }else{
        self.navigationItem.leftBarButtonItem = leftBarButon;
    }

AF网络检测

-(void)internet{
    
    [[AFNetworkReachabilityManager sharedManager] startMonitoring];
    //设置网络变化回调
    [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        switch (status) {
                
            case AFNetworkReachabilityStatusNotReachable:{
                NSLog(@"无网络");
                break;
            }
            case AFNetworkReachabilityStatusReachableViaWiFi:{
                NSLog(@"WiFi网络");
                if (!_weatherView.isLoad) {//如果weather没加载
                    [_weatherView download];
                }
                break;
            }
            case AFNetworkReachabilityStatusReachableViaWWAN:{
                NSLog(@"无线网络");
                if (!_weatherView.isLoad) {//如果weather没加载
                    [_weatherView download];
                }
                break;
            }
            default:
                break;
        }
    }];
}

AF的接受数据类型设置

manger.responseSerializer.acceptableContentTypes=[NSSet setWithObjects:@"application/json",@"text/html",@"text/plain", nil];

弹簧动画

[UIView animateWithDuration:0.2 delay:0.0 usingSpringWithDamping:1 initialSpringVelocity:0.5 options:UIViewAnimationOptionCurveEaseIn animations:^{
        _imageview.transform=CGAffineTransformMakeTranslation(0,-3);
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:0.5 delay:0.0 usingSpringWithDamping:0.3  initialSpringVelocity:5.0 options:UIViewAnimationOptionCurveLinear animations:^{
            _imageview.transform=CGAffineTransformMakeTranslation(0, 0);
        } completion:^(BOOL finished) {
            
        }];
    }];

判断代理实现代理方法

if(self.delegate&&[self.delegate respondsToSelector:@selector(SignBtnClick: ScoreLabel:)]){
        [self.delegate SignBtnClick:_TitleLabel ScoreLabel:_ScoreLabel];
    }

tabbar按钮自定义图片

user.tabBarItem.image = [[UIImage imageNamed:@"user"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

富文本改颜色

NSDictionary *dic =@{NSForegroundColorAttributeName:UIColorFromRGB(0xFE4500),NSFontAttributeName:[UIFont systemFontOfSize:13]};
[home.tabBarItem setTitleTextAttributes:dic forState:UIControlStateSelected];

态栏的颜色

self.navigationController.navigationBar.barStyle = UIBarStyleBlack;

改变导航栏上左右视图的位置

_weatherView=[[WeatherView alloc]initWithFrame:CGRectMake(0, 0, 45, 50)];
    UIBarButtonItem *leftBarButon = [[ UIBarButtonItem alloc ] initWithCustomView :_weatherView];
    if(([[[UIDevice currentDevice] systemVersion] floatValue]>=7.0?20:0)){
        UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
        negativeSpacer.width = -10;//这个数值可以根据情况自由变化
        self.navigationItem.leftBarButtonItems = @[negativeSpacer, leftBarButon];
    }else{
        self.navigationItem.leftBarButtonItem = leftBarButon;
    }

AF网络检测

-(void)internet{
    
    [[AFNetworkReachabilityManager sharedManager] startMonitoring];
    //设置网络变化回调
    [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        switch (status) {
                
            case AFNetworkReachabilityStatusNotReachable:{
                NSLog(@"无网络");
                break;
            }
            case AFNetworkReachabilityStatusReachableViaWiFi:{
                NSLog(@"WiFi网络");
                if (!_weatherView.isLoad) {//如果weather没加载
                    [_weatherView download];
                }
                break;
            }
            case AFNetworkReachabilityStatusReachableViaWWAN:{
                NSLog(@"无线网络");
                if (!_weatherView.isLoad) {//如果weather没加载
                    [_weatherView download];
                }
                break;
            }
            default:
                break;
        }
    }];
}

AF的接受数据类型设置

manger.responseSerializer.acceptableContentTypes=[NSSet setWithObjects:@"application/json",@"text/html",@"text/plain", nil];

Client.httpClient.responseSerializer = [AFHTTPResponseSerializer serializer];//不自动转换类型

AF设置超时

self.manager.requestSerializer.timeoutInterval 

判断代理实现代理方法

if(self.delegate&&[self.delegate respondsToSelector:@selector(SignBtnClick: ScoreLabel:)]){
        [self.delegate SignBtnClick:_TitleLabel ScoreLabel:_ScoreLabel];
    }

tabbar按钮自定义图片

user.tabBarItem.image = [[UIImage imageNamed:@"user"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

富文本改颜色

NSDictionary *dic =@{NSForegroundColorAttributeName:UIColorFromRGB(0xFE4500),NSFontAttributeName:[UIFont systemFontOfSize:13]};
[home.tabBarItem setTitleTextAttributes:dic forState:UIControlStateSelected];

富文本划线

 NSString *str=[NSString stringWithFormat:@"¥%.2f",[moudel.lastPrice floatValue]];
 NSDictionary *dict=@{NSStrikethroughStyleAttributeName:@(NSUnderlineStyleSingle|NSUnderlinePatternSolid),NSStrikethroughColorAttributeName:[UIColor grayColor]};
    NSMutableAttributedString *aStr=[[NSMutableAttributedString alloc]initWithString:str attributes:dict];
    _myLastPriceLabel.attributedText=aStr;

重写button上图片和文字的位置

-(CGRect)titleRectForContentRect:(CGRect)contentRect{
    return CGRectMake(0, 0, CGRectGetWidth(contentRect)*RATIO, CGRectGetHeight(contentRect));
}
//改变image的位置
-(CGRect)imageRectForContentRect:(CGRect)contentRect{
    return CGRectMake(CGRectGetWidth(contentRect)*RATIO, 0, CGRectGetWidth(contentRect)*(1-RATIO), CGRectGetHeight(contentRect));
}

设置导航栏标题

[self.navigationController.navigationBar setTitleTextAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:24],NSForegroundColorAttributeName:[UIColor magentaColor]}];

把图片存进相册

UIImageWriteToSavedPhotosAlbum(imageview.image, nil, nil, nil);

重绘系统cell图片大小

CGSize itemSize = CGSizeMake(60, 60);
UIGraphicsBeginImageContext(itemSize);
CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height);
[cell.imageView.image drawInRect:imageRect];
cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

设置cell选中后得背景颜色

cell.selectedBackgroundView=bgView;

隐藏cell分界线

Tableview.separatorStyle=UITableViewCellSeparatorStyleNone;

cell自适应会用重绘

[cell setNeedsDisplay];//将cell标识为需要重绘
[cell layoutIfNeeded];//cell如果需要重绘就重新绘制
tableView.estimatedRowHeight=CGRectGetMaxY(cell.MyCol.frame)+10;//预估算高度
tableView.rowHeight=UITableViewAutomaticDimension;//自适应高度

检测键盘弹出

[[NSNotificationCenter defaultCenter]addObserver:self   selector:@selector()  name:UIKeyboardWillShowNotification  object:nil];

第二部分

iOS调用系统相册、相机 显示中文标题

info.plist中添加
Localized resources can be mixed   设置为  YES

IOS8后IOS定位

在IOS8以后调用定位需要在info.plist里面加入两个属性
1.NSLocationAlwaysUsageDescription      
2.NSLocationWhenInUseUsageDescription
设置为String 值为1
不这样系统设置定位会蹦

判断GPS开启没

CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
    if (kCLAuthorizationStatusDenied == status || kCLAuthorizationStatusRestricted == status) {
        UIAlertController *alert=[UIAlertController alertControllerWithTitle:@"提示" message:@"请打开定位功能" preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
            
        }];
        [alert addAction:okAction];
        [[UIApplication sharedApplication].windows.firstObject.rootViewController presentViewController:alert animated:YES completion:^{
            
        }];
    }

请求用户授权

//如果没有授权则请求用户授权
    if ([CLLocationManager authorizationStatus]==kCLAuthorizationStatusNotDetermined){
        [_locationMgr requestAlwaysAuthorization];
        if([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0)
        {
            NSLog(@"是iOS8");
            // 主动要求用户对我们的程序授权, 授权状态改变就会通知代理
            [_locationMgr requestAlwaysAuthorization]; // 请求前台和后台定位权限
        }
    }else if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusAuthorizedAlways){
        //设置代理
        // _locationMgr.delegate=self;
        //设置定位精度
        _locationMgr.desiredAccuracy=kCLLocationAccuracyBest;
        //定位频率,每隔多少米定位一次
        CLLocationDistance distance=10.0;//十米定位一次
        _locationMgr.distanceFilter=distance;
        //启动跟踪定位
        [_locationMgr startUpdatingLocation];
    }

移除所有的子视图

[view.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

IOS自带表情上传服务器

[string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[string  stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

webview内存清理

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    [[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"WebKitCacheModelPreferenceKey"];
}

复制一段文字

 [[UIPasteboard generalPasteboard] setString:urlStr];

设置地区

NSLocale

若你只开发中国区的应用,需要保证用户修改当前语言环境时应用的显示不发生变化。而像NSDateFormatter这样的类,会根据设备的设置,自动返回不同语言的数据。为了保证返回数据的语言一致,我们需要设置NSLocale。
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh"];
NSDateFormatter *secondDateFormatter = [[NSDateFormatter alloc] init];
[secondDateFormatter setDateFormat:@"cccc"];
secondDateFormatter.locale = locale;
NSDate *date = [NSDate date];
NSLog(@"%@", [secondDateFormatter stringFromDate:date]);

信用卡判断

使用Luhn算法(Luhn algorithm)校验信用卡号的:

1、从卡号最右边开始,由右向左,奇数位数字直接累加;
2、从卡号最右边开始,由右向左,偶数位数字先乘以2(如果乘积为两位数,则将这两位数再次累加或者将其减去9),再求和。
例如:10 = 1 + 0 = 1, 14 = 1 + 4 = 5 等价于 10 - 9 = 1, 14 - 9 = 5;

3、将奇数位总和加上偶数位总和,结果对10取模为0。

例如,卡号是:356827027232780
奇数位和=28
偶数位乘以2(有些要减去9)的结果求和=32。
最后28+32=70 % 10 = 0,信用卡号校验通过。
- (BOOL)checkCreditCardNumber:(NSString *)cardNum
{
    NSAssert(cardNum && cardNum != @"" , @"checkCreditCardNumber: cardNum is nil.");
    NSInteger len = [cardNum length];
    NSInteger sumNumOdd = 0;
    NSInteger sumNumEven = 0;
    BOOL isOdd = YES;
    
    for (NSInteger i = len - 1; i >= 0; i--) {
        
        NSInteger num = [cardNum substringWithRange:NSMakeRange(i, 1)].integerValue;
        if (isOdd) {//奇数位
            sumNumOdd += num;
        }else{//偶数位
            num = num * 2;
            if (num > 9) {
                num = num - 9;
            }
            sumNumEven += num;
        }
        isOdd = !isOdd;
    }
    
    return ((sumNumOdd + sumNumEven) % 10 == 0);
}

uiwebview修改User-Agent

-(void)changeUserAgent{
    static int i=0;
    if(i++){
        return;
    }
    // 获取 iOS 默认的 UserAgent,可以很巧妙地创建一个空的UIWebView来获取
    NSString *userAgent = [[[UIWebView alloc]init] stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
    // 获取App名称,我的App有本地化支持,所以是如下的写法
    //NSString *appName = NSLocalizedStringFromTable(@"CFBundleDisplayName", @"InfoPlist", nil);
    NSString *version = [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"];
    NSString *customUserAgent = [userAgent stringByAppendingFormat:@" %@/%@", @"ios", version];
    [[NSUserDefaults standardUserDefaults] registerDefaults:@{@"UserAgent":customUserAgent}];
}

自定义导航栏返回按钮滑动返回失效解决办法

self.navigationController.interactivePopGestureRecognizer.delegate=(id)self;

RC4加密

+(NSString*)HloveyRC4:(NSString*)aInput key:(NSString*)aKey
{

    NSMutableArray *iS = [[NSMutableArray alloc] initWithCapacity:256];
    NSMutableArray *iK = [[NSMutableArray alloc] initWithCapacity:256];

    for (int i= 0; i<256; i++) {
        [iS addObject:[NSNumber numberWithInt:i]];
    }

    int j=1;

    for (short i=0; i<256; i++) {

        UniChar c = [aKey characterAtIndex:i%aKey.length];

        [iK addObject:[NSNumber numberWithChar:c]];
    }

    j=0;

    for (int i=0; i<255; i++) {
        int is = [[iS objectAtIndex:i] intValue];
        UniChar ik = (UniChar)[[iK objectAtIndex:i] charValue];

        j = (j + is + ik)%256;
        NSNumber *temp = [iS objectAtIndex:i];
        [iS replaceObjectAtIndex:i withObject:[iS objectAtIndex:j]];
        [iS replaceObjectAtIndex:j withObject:temp];

    }

    int i=0;
    j=0;

    NSString *result = aInput;

    for (short x=0; x<[aInput length]; x++) {
        i = (i+1)%256;

        int is = [[iS objectAtIndex:i] intValue];
        j = (j+is)%256;

        int is_i = [[iS objectAtIndex:i] intValue];
        int is_j = [[iS objectAtIndex:j] intValue]; 

        int t = (is_i+is_j) % 256;
        int iY = [[iS objectAtIndex:t] intValue];

        UniChar ch = (UniChar)[aInput characterAtIndex:x];
        UniChar ch_y = ch^iY;

        result = [result stringByReplacingCharactersInRange:NSMakeRange(x, 1) withString:[NSString stringWithCharacters:&ch_y length:1]];
    }

    [iS release];
    [iK release];

    return result;
}

将一个UIView对象的内容保存为UIImage

+ (UIImage*)imageFromView:(UIView*)view{
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, view.layer.contentsScale);
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

截取屏幕图片

// 创建一个基于位 图的图形上下文并指定大小为CGSizeMake(200,400) 
UIGraphicsBeginImageContext(CGSizeMake(200,400));  

//renderInContext  呈现接受者及其子范围到 指定的上下文 
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()]; 

// 返回 一个基于当前图形上下文的图片 
UIImage *aImage = UIGraphicsGetImageFromCurrentImageContext(); 
// 移除栈顶 的基于当前位图的图形上下文 
UIGraphicsEndImageContext(); 
// 以 png 格式 返回指定图片的数据 
imageData = UIImagePNGR epresentation(aImage);  

present一个半透明的视图

	TestViewController * testVC = [TestViewController new];
    self.definesPresentationContext = YES; //self is presenting view controller
    testVC.view.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:.4];
    testVC.modalPresentationStyle = UIModalPresentationOverCurrentContext;
    [self presentViewController:testVC animated:YES completion:nil];

present一个半透明的带导航栏的视图

    SecondViewController * testVC = [SecondViewController new];
    self.definesPresentationContext = YES; //self is presenting view controller
    testVC.view.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:.5];
//    testVC.modalPresentationStyle = UIModalPresentationOverCurrentContext;
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:testVC];
    nav.modalPresentationStyle = UIModalPresentationOverCurrentContext;
    nav.view.backgroundColor = [UIColor clearColor];
    [self presentViewController:nav animated:YES completion:nil];

防止类是不存在的

Class class = NSClassFromString(@"SecondViewController");
    if (class) {
        UIViewController *vc = [class new];
        [self.navigationController pushViewController:vc animated:YES];
    }

AFHTTPSessionManager

AFHTTPSessionManager *sess = [AFHTTPSessionManager manager];
    sess.requestSerializer.timeoutInterval = 30;//设置超时
    [sess.requestSerializer setValue:Client.token forHTTPHeaderField:@"token"];
    sess.responseSerializer.acceptableContentTypes=[NSSet setWithObjects:@"application/json",@"text/html",@"text/plain", nil];
    [sess GET:urlStr parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
        [self analysisWithDic:responseObject];//解析数据
    } failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) {
        [_tableview.header endRefreshing];
        [_tableview.footer endRefreshing];
        [SVProgressHUD showInfoWithStatus:@"请检查您的网络连接!"];
        NSLog(@"%@",error);
    }];

URL编码

1.url编码

ios中http请求遇到汉字的时候,需要转化成UTF-8,用到的方法是:

NSString * encodingString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

2.url解码

请求后,返回的数据,如何显示的是这样的格式:%3A%2F%2F,此时需要我们进行UTF-8解码,用到的方法是:

NSString *str = [model.album_name stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];