<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont

简介: 每日更新关注:http://weibo.com/hanjunqiang  新浪微博!手机加iOS开发者交流QQ群: 4463102061.

每日更新关注:http://weibo.com/hanjunqiang  新浪微博!手机加iOS开发者交流QQ群: 446310206

1.iOS - 推送 openssl 合并
//1.1 生成 opensslkey
openssl pkcs12 -nocerts -out PushKey.pem -in apns-dev-cert.p12
//1.2 输入以上成功之后会出现以下这段:
Enter PEM pass phrase:输入密码
//2.导出 pem
openssl pkcs12 -clcerts -nokeys -out apns-dev-cert.pem -in apns-dev-cert.p12
//3.将 key 和 pem 合并
cat PushKey.pem apns-dev-cert.pem > apns-Dev.pem
===========================================================================================================

2.Cookie(小甜饼 )
//cookie
介绍
Cookie
由服务器端生成,发送给客户端
客户端将 Cookie key/value 保存到某个目录下的文本文件内
如果客户端支持 Cookie ,下次请求同一网站时就可以 Cookie 直接发送给服务器
Cookie
名称和值由服务器端开发自己定义
Cookies
最典型的应用是判定注册用户是否已经登录,记录用户登录信息,简化下次登录的过程
另一个重要应用场合是 购物车
iOS 程序中,默认就支持 Cookie ,程序员无需做任何处理
如果服务器返回 Cookie ,会自动保存在沙盒的 Library/Cookies 目录中

/* Cookie的存储策略 */

 
 @property NSHTTPCookieAcceptPolicy cookieAcceptPolicy;
 
 NSHTTPCookieAcceptPolicyAlways,                    永远
 NSHTTPCookieAcceptPolicyNever,                     永不
 NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain 只记录主域名的Cookie
 
 //提示:如果禁用Cookie有些网络访问会不正常!
 //这个选项只要知道即可,不建议修改!

 
/* Cookie
的保存 */
 
 
保存在 沙盒 /Library/Cookies 目录下,以二进制的形式保存
 
但是仍然能够看到密码的明文,说明不安全!
 
 
/*
获取 cookie 的方法 */
// 检查Cookie中是否保存了用户的信息
    
// 1. 拿出所有的cookie
NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
    
// 2. 遍历cookies检查是否有用户名和密码
for (NSHTTPCookie *cookie in cookies) {
    /**
        NSHTTPCookie中存储的内容
         
        name: 变量名->变量名&值是从服务器返回的
        value: 变量值
    */
    NSLog(@"%@", cookie);
    if ([cookie.name isEqualToString:@"userName"]) { // 用户名
        self.nameText.text = cookie.value;
    } else if ([cookie.name isEqualToString:@"userPassword"]) { // 密码
        self.pwdText.text = cookie.value;
    }
}

// 3. 删除Cookie
// 读取所有cookie
NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
 
// 删除cookie
for (NSHTTPCookie *cookie in cookies) {
    [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
}

 
/* Cookie
的缺陷 */
Cookie
会被附加在每个HTTP请求中,会增加额外的流量
HTTP请求中的Cookie是明文传递的,因此会有安全隐患,除非使用HTTPS

Cookie的大小限制在4KB左右,不适合存储复杂的数据信息

===========================================================================================================


3.截图使用场景: iOS 7中的代码代段

// 使用上下文截图,并使用指定的区域裁剪,模板代码
- (void)screenShot
{
    // 将要被截图的view,即窗口的根控制器的view(必须不含状态栏,默认ios7中控制器是包含了状态栏的)
    BeyondViewController *beyondVC = self.view.window.rootViewController;
    // 背景图片 总的大小
    CGSize size = beyondVC.view.frame.size;
    // 开启上下文,使用参数之后,截出来的是原图(YES  0.0 质量高)
    UIGraphicsBeginImageContextWithOptions(size, YES, 0.0);
    // 裁剪的关键代码,要裁剪的矩形范围
    CGRect rect = CGRectMake(0, -20, size.width, size.height + 20 );
    //注:iOS7以后renderInContext:由drawViewHierarchyInRect:afterScreenUpdates:替代
    [beyondVC.view drawViewHierarchyInRect:rect  afterScreenUpdates:NO];
    // 从上下文中,取出UIImage
    UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext();
    // 添加截取好的图片到图片数组
    [_cutImages addObject:snapshot];
     
    // 千万记得,结束上下文(移除栈顶上下文)
    UIGraphicsEndImageContext();
     
}


===========================================================================================================

4.解决UIButton 按钮重复点击
配合Github上我写的扩展使用,简单实用:
https://github.com/XiaoHanGe/JQButtonRepeatClick

 // test
    UIButton *testBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    
    testBtn.frame = CGRectMake(100, 100, [UIScreen mainScreen].bounds.size.width-200, [UIScreen mainScreen].bounds.size.height/3);
    
    testBtn.backgroundColor = [UIColor greenColor];
    [testBtn setTitleColor:[UIColor redColor] forState:(UIControlStateNormal)];
    [testBtn setTitle:@"测试" forState:UIControlStateNormal];
    
    [testBtn addTarget:self action:@selector(goToTestAction:) forControlEvents:UIControlEventTouchUpInside];
    // 设置几秒内忽略重复点击
    testBtn.JQ_acceptEventInterval = 1;
    
    [self.view addSubview:testBtn];

每日更新关注:http://weibo.com/hanjunqiang  新浪微博!手机加iOS开发者交流QQ群: 446310206

===========================================================================================================

5.#pragma mark -- 设置在一个文本中所有特殊字符的特殊颜色
+ (NSMutableAttributedString *)setAllText:(NSString *)allStr andSpcifiStr:(NSString *)specifiStr withColor:(UIColor *)color specifiStrFont:(UIFont *)font {
 
    NSMutableAttributedString *mutableAttributedStr = [[NSMutableAttributedString alloc] initWithString:allStr];
    if (color == nil) {
        color = [UIColor redColor];
    }
    if (font == nil) {
        font = [UIFont systemFontOfSize:17.];
    }
    //    NSArray *array = [allStr componentsSeparatedByString:specifiStr];//array.cout-1是所有字符特殊字符出现的次数
     NSRange searchRange = NSMakeRange(0, [allStr length]);
     NSRange range;
    //拿到所有的相同字符的range
     while
         ((range = [allStr rangeOfString:specifiStr options:0 range:searchRange]).location != NSNotFound) {
         //改变多次搜索时searchRange的位置
         searchRange = NSMakeRange(NSMaxRange(range), [allStr length] - NSMaxRange(range));
         //设置富文本
         [mutableAttributedStr addAttribute:NSForegroundColorAttributeName value:color range:range];
         [mutableAttributedStr addAttribute:NSFontAttributeName value:font range:range];
     }
    return mutableAttributedStr;
}

===========================================================================================================


6. 放大缩小
// 放大
- (void)shakeToShow:(UIButton*)aView{
    CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
    animation.duration = 0.5;
   
    NSMutableArray *values = [NSMutableArray array];
    [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 1.0)]];
    [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.2, 1.2, 1.0)]];
    [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.9, 0.9, 1.0)]];
    [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.0, 1.0, 1.0)]];
    animation.values = values;
    [aView.layer addAnimation:animation forKey:nil];
}
// 缩小
- (void)shakeToHidden:(UIButton*)aView{
    CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
    animation.duration = 0.5;
   
    NSMutableArray *values = [NSMutableArray array];
    [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.0, 1.0, 1.0)]];
    [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.9, 0.9, 1.0)]];
    [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.2, 1.2, 1.0)]];
    [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 1.0)]];
    animation.values = values;
    [aView.layer addAnimation:animation forKey:nil];
}
- (void)showWithAView:(UIButton*)aView
{
    [CATransaction begin]; {
        // start the transform animation from its current value if it's already running
        NSValue *fromValue = [aView.layer animationForKey:@"transform"] ? [aView.layer.presentationLayer valueForKey:@"transform"] : [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.5, 0.5, 1)];
       
        CABasicAnimation *scaleAnim = [CABasicAnimation animationWithKeyPath:@"transform"];
        scaleAnim.fromValue = fromValue;
        scaleAnim.toValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
        [scaleAnim setTimingFunction:[CAMediaTimingFunction functionWithControlPoints:0.8 :2.5 :0.35 :0.5]];
        scaleAnim.removedOnCompletion = NO;
        scaleAnim.fillMode = kCAFillModeForwards;
        scaleAnim.duration = 0.4;
        [aView.layer addAnimation:scaleAnim forKey:@"transform"];
       
        CABasicAnimation* fadeInAnim = [CABasicAnimation animationWithKeyPath:@"opacity"];
        fadeInAnim.fromValue = [aView.layer.presentationLayer valueForKey:@"opacity"];
        fadeInAnim.duration = 0.1;
        fadeInAnim.toValue = @1.0;
        [aView.layer addAnimation:fadeInAnim forKey:@"opacity"];
       
        aView.layer.opacity = 1.0;
    } [CATransaction commit];
}

- (void)hideWithAView:(UIButton*)aView
{
    [CATransaction begin]; {
        [CATransaction setCompletionBlock:^{
            // remove the transform animation if the animation finished and wasn't interrupted
            if (aView.layer.opacity == 0.0) [aView.layer removeAnimationForKey:@"transform"];
           
        }];
       
        CABasicAnimation *scaleAnim = [CABasicAnimation animationWithKeyPath:@"transform"];
        scaleAnim.fromValue = [aView.layer.presentationLayer valueForKey:@"transform"];
        scaleAnim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.5, 0.5, 1)];
        scaleAnim.duration = 0.6;
        scaleAnim.removedOnCompletion = NO;
        scaleAnim.fillMode = kCAFillModeForwards;
        [scaleAnim setTimingFunction:[CAMediaTimingFunction functionWithControlPoints:0.1 :-2 :0.3 :3]];
        [aView.layer addAnimation:scaleAnim forKey:@"transform"];
       
        CABasicAnimation* fadeOutAnim = [CABasicAnimation animationWithKeyPath:@"opacity"];
        fadeOutAnim.fromValue = [aView.layer.presentationLayer valueForKey:@"opacity"];
        fadeOutAnim.toValue = @0.0;
        fadeOutAnim.duration = 0.8;
        [aView.layer addAnimation:fadeOutAnim forKey:@"opacity"];
        aView.layer.opacity = 0.0;
    } [CATransaction commit];
}


===========================================================================================================


7.#pragma mark - 抖动动画
- (void)shakeAnimation
{
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position.x"];
    //获取当前View的position坐标
    CGFloat positionX = self.layer.position.x;
    //设置抖动的范围
    animation.values = @[@(positionX-10),@(positionX),@(positionX+10)];
    //动画重复的次数
    animation.repeatCount = 3;
    //动画时间
    animation.duration = 0.07;
    //设置自动反转
    animation.autoreverses = YES;
    [self.layer addAnimation:animation forKey:nil];
}

===========================================================================================================

8.iOS - 直接退出应用
//使用
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    [self exitApplication];
}

//退出方法
- (void)exitApp {
[UIView beginAnimations:@"exitApplication" context:nil];
 [UIView setAnimationDuration:0.5]; 
[UIView setAnimationDelegate:self]; 
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view.window cache:NO]; 
[UIView setAnimationDidStopSelector:@selector(animationFinished:finished:context:)];
 self.view.window.bounds = CGRectMake(0, 0, 0, 0); 
[UIView commitAnimations];
}
- (void)animationFinished:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context { 
if ([animationID compare:@"exitApplication"] == 0) 
{
 //退出
   exit(0);
 }
}

===========================================================================================================


9.iOS - 图片模糊效果
vImage 方式添加通用模糊效果
#import <Accelerate/Accelerate.h>
//加模糊效果,image是图片,blur是模糊度
- (UIImage *)blurryImage:(UIImage *)image withBlurLevel:(CGFloat)blur
{
    if (image==nil)
    {
       NSLog(@"error:为图片添加模糊效果时,未能获取原始图片");
        return nil;
    }
//模糊度,
    if ((blur < 0.1f) || (blur > 2.0f)) {
        blur = 0.5f;
    }

    //boxSize必须大于0
    int boxSize = (int)(blur * 100);
    boxSize -= (boxSize % 2) + 1;
    NSLog(@"boxSize:%i",boxSize);
    //图像处理
    CGImageRef img = image.CGImage;
    //需要引入#import <Accelerate/Accelerate.h>
    /*
     This document describes the Accelerate Framework, which contains C APIs for vector and matrix math, digital signal processing, large number handling, and image processing.
     本文档介绍了Accelerate Framework,其中包含C语言应用程序接口(API)的向量和矩阵数学,数字信号处理,大量处理和图像处理。
     */

    //图像缓存,输入缓存,输出缓存
    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);
    //CGColorSpaceRelease(colorSpace);   //多余的释放
    CGImageRelease(imageRef);
    return returnImage;
}

===========================================================================================================

10.优化建议

优化建议:
避免图层混合
· 确保控件的opaque属性设置为true,确保backgroundColor和父视图颜色一致且不透明
· 如无特殊需要,不要设置低于1alpha
· 确保UIImage没有alpha通道
避免临时转换
· 确保图片大小和frame一致,不要在滑动时缩放图片
· 确保图片颜色格式被GPU支持,避免劳烦CPU转换
慎用离屏渲染
· 绝大多数时候离屏渲染会影响性能
· 重写drawRect方法,设置圆角、阴影、模糊效果,光栅化都会导致离屏渲染
· 设置阴影效果是加上阴影路径
· 滑动时若需要圆角效果,开启光栅化

===========================================================================================================


11.iOS - 收起键盘
对应控件 resignFirstResponder
touchesBegin 中
[self.view endEditing:YES];

[[UIApplication sharedApplication]sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];

[[[UIApplication sharedApplication]keyWindow]endEditing:YES];

===========================================================================================================

12.tab Bar的隐藏与消失
// tabBar的隐藏与消失
- (void)hidesTabBar:(BOOL)hidden{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0];
   
    for (UIView *view in self.tabBarController.view.subviews){
       
        if ([view isKindOfClass:[UITabBar class]]) {
            if (hidden) {
                [view setFrame:CGRectMake(view.frame.origin.x, [UIScreen mainScreen].bounds.size.height, view.frame.size.width , view.frame.size.height)];
            }else{
                [view setFrame:CGRectMake(view.frame.origin.x, [UIScreen mainScreen].bounds.size.height - 49, view.frame.size.width, view.frame.size.height)];
            }
        }else{
            if([view isKindOfClass:NSClassFromString(@"UITransitionView")]){
                if (hidden){
                    [view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, [UIScreen mainScreen].bounds.size.height)];
                }else{
                   
                    [view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, [UIScreen mainScreen].bounds.size.height - 49 )];
                }
            }
        }
    }
    [UIView commitAnimations];
}


===========================================================================================================


13.判断页面消失或出现时是push还是pop操作:
- (void)viewWillDisappear:(BOOL)animated {
    NSArray *viewControllers = self.navigationController.viewControllers;//获取当前的视图控制其
    if (viewControllers.count > 1 && [viewControllers objectAtIndex:viewControllers.count-2] == self) {
        //当前视图控制器在栈中,故为push操作
        NSLog(@"push");
    } else if ([viewControllers indexOfObject:self] == NSNotFound) {
        //当前视图控制器不在栈中,故为pop操作
        NSLog(@"pop");
    }
}


每日更新关注:http://weibo.com/hanjunqiang  新浪微博!手机加iOS开发者交流QQ群: 446310206

目录
相关文章
|
7月前
OA会议管理系统之我的审批(审批签字可生成图片)(二)
OA会议管理系统之我的审批(审批签字可生成图片)(二)
2948 0
|
10月前
|
存储 缓存 Linux
Git入门操作手册
Git入门操作手册
186 1
|
10月前
|
JavaScript 前端开发
网易严选商城前端实现-vue
网易严选商城前端实现-vue
193 0
|
10月前
|
机器学习/深度学习 人工智能
2017蓝桥杯省赛C++B组真题与题解(三)
2017蓝桥杯省赛C++B组真题与题解
1526 1
|
10月前
|
网络安全 PHP
PHPcurl访问HTTPS网址出错解决方法
PHPcurl访问HTTPS网址出错解决方法
|
11月前
|
存储 XML 安全
网安渗透测试面试集1
网安渗透测试面试集1
|
11月前
|
数据采集 消息中间件 分布式计算
大数据数据采集的数据采集(收集/聚合)的Flume之概念
在大数据应用中,数据采集是非常重要的一步。Flume是一个开源的分布式系统,可以帮助企业完成数据采集、收集和聚合等操作,并将它们发送到后续处理系统中。
195 0
|
11月前
|
网络协议
Job for named.service failed because the control process exited with error code.
Job for named.service failed because the control process exited with error code.
509 0
|
11月前
|
域名解析 存储 编解码
C1认证学习笔记(第一章)
C1认证学习笔记(第一章)
255 0
|
11月前
|
机器学习/深度学习 人工智能 数据挖掘
【Pytorch神经网络理论篇】 26 基于空间域的图卷积GCNs(ConvGNNs):定点域+谱域+图卷积的操作步骤
图卷积网络(Graph Convolutional Network,GCN)是一种能对图数据进行深度学习的方法。图卷积中的“图”是指数学(图论)中用顶点和边建立的有相关联系的拓扑图,而积指的是“离散卷积”,其本质就是一种加权求和,加权系数就是卷积核的权重系数。
181 0