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 *)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
//加模糊效果,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
/*
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和父视图颜色一致且不透明
· 如无特殊需要,不要设置低于1的alpha值
· 确保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