qg777钱柜误乐

热门关键词: qg777钱柜误乐

Dynamic支持CollectionView布局 、 MotionEffects特效 、 BlurImage效果 、 TextKit

图片 1

1 使用UIDynamicAnimator对集合视图进行布局

       

在iOS开发中会遇到模糊图片的,这里给大家介绍一个可以模糊掉图片指定区域的防范,原文:更多解决方案也请看上边链接设置UIImageView的属性名字为:imageView,然后同一序列添加下面四个方法到实现文件中,然后设置ImageViewMode为Redraw,添加模糊效果的UIImage自定义或默认类,就OK了。method1-剪裁图片

1.1 问题

UIKit Dynamic动力模型一个非常有趣的用途就是影响集合视图的布局,可以给集合视图的布局添加各种动力行为,使其产生丰富多彩的效果,本案例使用UIDynamicAnimator对集合视图进行布局,实现一个弹性列表,如图-1所示:

图片 2

图-1

最近想找有关Runtime的文章,找了好久都不太满意,讲解的模糊不清,偶然的机会发现了一个一行代码,足解决大家所有有关Runtime问题的方法,废话不多说在此奉上[OC_runtime运行时官方文档翻译_IThao123

IT行业第一站]()

在这里简单给大家说下Runtime的部分功能,

首先,Runtime是一套底层的C语言API(包含强大的C语言数据类型和函数)

OC代码都是基于Runtime实现的,即编写的OC代码最终都会转成Runtime的代码,

例如

 HCPerson *person = [HCPerson alloc]    init];

 [person setAge:10]; //这句会转换成objc_msgSend(person,@selector(setAge:),20);

他的作用:

*能获得某个类的所有成员变量

*能获得某个类的所有属性

*能获得某个类的所有方法

*交换方法实现(调用A的方法名但是会去执行B的方法)

*能动态添加一个成员变量

*能动态添加一个属性

*能动态添加一个方法

如果有这么个需求:要求对iOS8-和iOS8+的图片进行适配,不同系统版本显示不同的图片,并且在加载图片的时候做个图片是否加载成功做个判断

实现方法:

1.需求是对图片做操作,那么就要给UIImage搞个分类,然后导入消息机制头文件

#import<objc/message.h> 漏掉这个你是敲不出Method 类的

具体代码实现:

```code_lang

#import "UIImage+MyImage.h"

#import<objc/message.h>

@implementation UIImage (MyImage)

+(void)load

{

// 获取imageName地址

Method imageName = class_getClassMethod(self, @selector(imageNamed:));

// 获取imageWithName地址

Method imageWithName = class_getClassMethod(self, @selector(imageWithName:));

//交换两个方法的地址,实际上就是交换实现方式

method_exchangeImplementations(imageName, imageWithName);

}

// 既能加载图片又能打印

+ (instancetype)imageWithName:(NSString *)name

{

BOOL isiOS8= [[UIDevice currentDevice].systemVersion floatValue] >= 8.0;

UIImage *image = nil;

if (isiOS8) {

NSString *newName = [name stringByAppendingString:@"_iOS8+"];

image = [UIImage imageWithName:newName];

}

// 这里调用ImageWithName 相当于调用imageName

UIImage *image = [self imageWithName:name];

if (image == nil) {

NSLog(@"图片为空");

}

return image;

}

@end

       

#pragmamark-CropingtheImage-(UIImage*)croppIngimageByImageName:(UIImage*)imageToCroptoRect:(CGRect)rect{CGImageRefimageRef=CGImageCreateWithImageInRect([imageToCropCGImage],rect);UIImage*cropped=[UIImageimageWithCGImage:imageRef];CGImageRelease(imageRef);returncropped;}

1.2 方案

首先创建一个SingleViewApplication项目,给UIColor类创建一个分类UIColor+RandomColor,提供一个产生随机颜色的静态方法randomColor。

其次创建一个自定义布局类TRCollectionViewSpringCellLayout继承至UICollectionViewFlowLayout,该类有一个UIDynamicAnimator类型的属性animator。重写prepareLayout方法(该方法在布局开始前自动调用),在该方法中使用initWithCollectionViewLayout:创建animator对象,然后给每个items都添加UIAttachmentBehavior行为。

然后实现layoutAttributesForElementsInRect: 和 layoutAttributesForItemAtIndexPath: 这两个方法,程序运行的时候会通过调用它们来询问 collectionView每一个 item 的布局信息。

再实现shouldInvalidateLayoutForBoundsChange:,该方法会在集合视图的 bounds发生改变的时候被调用,根据最新的contentOffset 调整animator中behaviors 的参数,在重新调整之后该方法返回NO。

最后在TRViewController的viewDidLoad方法中使用TRCollectionViewSpringCellLayout对象创建集合视图collectionView,并且实现集合视图的协议方法给集合视图加载数据。

Method2-

1.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建UIColor分类

首先创建一个SingleViewApplication项目,给UIColor类创建一个分类UIColor+RandomColor,提供一个产生随机颜色的静态方法randomColor,代码如下所示:

 

    • (UIColor *)randomColor
  1. {
  2. CGFloat red = arc4random() % 256 / 256.0;
  3. CGFloat green = arc4random() % 256 / 256.0;
  4. CGFloat blue = arc4random() % 256 / 256.0;
  5. return [UIColor colorWithRed:red green:green blue:blue alpha:1.0];
  6. }

步骤二:创建自定义布局类TRCollectionViewSpringCellLayout

首先创建一个自定义布局类TRCollectionViewSpringCellLayout继承至UICollectionViewFlowLayout,该类有一个UIDynamicAnimator类型的属性animator,代码如下所示:

  1. @interface TRCollectionViewSpringCellLayout ()
  2. @property (strong, nonatomic) UIDynamicAnimator *animator;
  3. @end

其次重写prepareLayout方法(该方法在布局开始前自动调用),在该方法中使用initWithCollectionViewLayout:创建animator对象,然后给每个items都添加UIAttachmentBehavior行为,代码如下所示:

 

  1. //布局前的准备,布局开始前自动调用
    • (void)prepareLayout
  2. {
  3. if(!self.animator){
  4. //通过集合视图布局创建animator对象
  5. self.animator = [[UIDynamicAnimator alloc]initWithCollectionViewLayout:self];
  6. CGSize contentSize = self.collectionViewContentSize;
  7. //获取所有的items
  8. NSArray *items = [super layoutAttributesForElementsInRect:CGRectMake(0, 0, contentSize.width, contentSize.height)];
  9. //给每个一Cell创建UIAttachmentBehavior
  10. for (UICollectionViewLayoutAttributes *attributes in items) {
  11. UIAttachmentBehavior *spring = [[UIAttachmentBehavior alloc]initWithItem:attributes attachedToAnchor:attributes.center];
  12. spring.damping = 0.6;
  13. spring.frequency = 0.8;
  14. [self.animator addBehavior:spring];
  15. }
  16. }
  17. }

然后实现layoutAttributesForElementsInRect: 和 layoutAttributesForItemAtIndexPath: 这两个方法,程序运行的时候会通过调用它们来询问 collectionView每一个 item 的布局信息,代码如下所示:

 

  1. //在集合视图滚动时会自动调用,返回所有cell的属性,并传递可见的矩形区域
    • (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
  2. {
  3. //当collectionView需要layout信息时由animator提供
  4. return [self.animator itemsInRect:rect];
  5. }
    • (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
  6. {
  7. return [self.animator layoutAttributesForCellAtIndexPath:indexPath];
  8. }

最后实现shouldInvalidateLayoutForBoundsChange:,该方法会在集合视图的 bounds发生改变的时候被调用,根据最新的contentOffset 调整animator中behaviors 的参数,在重新调整之后该方法返回NO,代码如下所示:

 

  1. //当bounds发生变化时,调用方法,为不同的Cell改变不同的锚点
    • (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
  2. {
  3. UIScrollView *scrollView = self.collectionView;
  4. //获取滚动的距离
  5. CGFloat scrollDelta = newBounds.origin.y
    • scrollView.bounds.origin.y;
  6. //手指所在的位置
  7. CGPoint touchLocation = [scrollView.panGestureRecognizer locationInView:scrollView];
  8. //计算和改动每一个Cell的锚点
  9. for (UIAttachmentBehavior *spring in self.animator.behaviors) {
  10. UICollectionViewLayoutAttributes *item = [spring.items firstObject];
  11. CGPoint center = item.center;
  12. CGPoint anchorPoint = spring.anchorPoint;
  13. CGFloat distance = fabsf(touchLocation.y - anchorPoint.y);
  14. CGFloat scrollResistance = distance / 600;
  15. center.y += (scrollDelta>0)?MIN(scrollDelta, scrollDelta * scrollResistance):MAX(scrollDelta, scrollDelta * scrollResistance);
  16. item.center = center;
  17. //当item处于动画中时,如果对象主动修改了位置信息,需要更新动画
  18. [self.animator updateItemUsingCurrentState:item];
  19. }
  20. return NO;
  21. }

步骤四:遵守委托协议,实现协议方法

首先在TRViewController的viewDidLoad方法中创建TRCollectionViewSpringCellLayout对象layout,并设置相关属性,代码如下所示:

 

    • (void)viewDidLoad
  1. {
  2. [super viewDidLoad];
  3.     TRCollectionViewSpringCellLayout *layout = [[TRCollectionViewSpringCellLayout alloc]init];
  4. layout.itemSize = CGSizeMake(300, 40);
  5. layout.sectionInset = UIEdgeInsetsMake(0, 10, 0, 10);
  6. }

然后通过layout创建collectionView,并注册Cell,代码如下所示:

 

  1. static NSString *cellIdentifier = @"MyCell";
    • (void)viewDidLoad
  2. {
  3. [super viewDidLoad];
    1.     TRCollectionViewSpringCellLayout *layout = [[TRCollectionViewSpringCellLayout alloc]init];
  4. layout.itemSize = CGSizeMake(300, 40);
  5. layout.sectionInset = UIEdgeInsetsMake(0, 10, 0, 10);
  6. UICollectionView *collectionView = [[UICollectionView alloc]initWithFrame:self.view.frame collectionViewLayout:layout];
  7. collectionView.showsVerticalScrollIndicator = NO;
  8. collectionView.showsHorizontalScrollIndicator = NO;
  9. collectionView.dataSource = self;
  10. [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:cellIdentifier];
  11. [self.view addSubview:collectionView];
  12. }

最后实现集合视图的协议方法给集合视图加载数据,代码如下所示:

 

    • (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
  1. {
  2. return 50;
  3. }
      • (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
  4. {
  5. UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
  6. cell.backgroundColor = [UIColor randomColor];
  7. return cell;
  8. }
#pragmamark-MargetwoImages-(UIImage*)addImageToImage:(UIImage*)imgwithImage2:(UIImage*)img2andRect:(CGRect)cropRect{CGSizesize=CGSizeMake(imageView.image.size.width,imageView.image.size.height);UIGraphicsBeginImageContext(size);CGPointpointImg1=CGPointMake(0,0);[imgdrawAtPoint:pointImg1];CGPointpointImg2=cropRect.origin;[img2drawAtPoint:pointImg2];UIImage*result=UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();returnresult;}

1.4 完整代码

本案例中,TRViewController.m文件中的完整代码如下所示:

 

  1. #import "TRViewController.h"
  2. #import "TRCollectionViewSpringCellLayout.h"
  3. #import "UIColor+RandomColor.h"
    1. @implementation TRViewController
  4. static NSString *cellIdentifier = @"MyCell";
    • (void)viewDidLoad
  5. {
  6. [super viewDidLoad];
    1.     TRCollectionViewSpringCellLayout *layout = [[TRCollectionViewSpringCellLayout alloc]init];
  7. layout.itemSize = CGSizeMake(300, 40);
  8. layout.sectionInset = UIEdgeInsetsMake(0, 10, 0, 10);
    1. UICollectionView *collectionView = [[UICollectionView alloc]initWithFrame:self.view.frame collectionViewLayout:layout];
  9. collectionView.showsVerticalScrollIndicator = NO;
  10. collectionView.showsHorizontalScrollIndicator = NO;
  11. collectionView.dataSource = self;
    1. [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:cellIdentifier];
  12. [self.view addSubview:collectionView];
    1. }
      • (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
  13. {
  14. return 50;
  15. }
      • (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
  16. {
  17. UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
  18. cell.backgroundColor = [UIColor randomColor];
  19. return cell;
  20. }
  21. @end 

本案例中,TRCollectionViewSpringCellLayout.m文件中的完整代码如下所示:

 

  1. #import "TRCollectionViewSpringCellLayout.h"
    1. @interface TRCollectionViewSpringCellLayout ()
  2. @property (strong, nonatomic) UIDynamicAnimator *animator;
  3. @end
    1. @implementation TRCollectionViewSpringCellLayout
    1. //布局前的准备,布局开始前自动调用
    • (void)prepareLayout
  4. {
  5. //给每个一Cell创建UIAttachmentBehavior
  6. if(!self.animator){
  7. //通过集合视图布局创建animator对象
  8. self.animator = [[UIDynamicAnimator alloc]initWithCollectionViewLayout:self];
  9. CGSize contentSize = self.collectionViewContentSize;
  10. //获取所有的items
  11. NSArray *items = [super layoutAttributesForElementsInRect:CGRectMake(0, 0, contentSize.width, contentSize.height)];
  12. for (UICollectionViewLayoutAttributes *attributes in items) {
  13. UIAttachmentBehavior *spring = [[UIAttachmentBehavior alloc]initWithItem:attributes attachedToAnchor:attributes.center];
  14. spring.damping = 0.6;
  15. spring.frequency = 0.8;
  16. [self.animator addBehavior:spring];
  17. }
  18. }
  19. }
  20. //在集合视图滚动时会自动调用,返回所有cell的属性,并传递可见的矩形区域
    • (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
  21. {
  22. //当collectionView需要layout信息时由animator提供
  23. return [self.animator itemsInRect:rect];
  24. }
      • (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
  25. {
  26. return [self.animator layoutAttributesForCellAtIndexPath:indexPath];
  27. }
    1. //当bounds发生变化时,调用方法,为不同的Cell改变不同的锚点
    • (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
  28. {
  29. UIScrollView *scrollView = self.collectionView;
  30. //获取滚动的距离
  31. CGFloat scrollDelta = newBounds.origin.y
    • scrollView.bounds.origin.y;
  32. //手指所在的位置
  33. CGPoint touchLocation = [scrollView.panGestureRecognizer locationInView:scrollView];
  34. //计算和改动每一个Cell的锚点
  35. for (UIAttachmentBehavior *spring in self.animator.behaviors) {
  36. UICollectionViewLayoutAttributes *item = [spring.items firstObject];
  37. CGPoint center = item.center;
  38. CGPoint anchorPoint = spring.anchorPoint;
  39. CGFloat distance = fabsf(touchLocation.y - anchorPoint.y);
  40. CGFloat scrollResistance = distance / 600;
  41. center.y += (scrollDelta>0)?MIN(scrollDelta, scrollDelta * scrollResistance):MAX(scrollDelta, scrollDelta * scrollResistance);
  42. item.center = center;
  43. //当item处于动画中时,如果对象主动修改了位置信息, 需要更新动画
  44. [self.animator updateItemUsingCurrentState:item];
  45. }
  46. return NO;
  47. }
  48. @end 

本案例中,UIColor+RandomColor.h文件中的完整代码如下所示:

 

  1. #import <UIKit/UIKit.h>
  2. @interface UIColor (RandomColor)
    • (UIColor *)randomColor;
  3. @end 

本案例中,UIColor+RandomColor.m文件中的完整代码如下所示:

 

  1. #import "UIColor+RandomColor.h"
  2. @implementation UIColor (RandomColor)
    • (UIColor *)randomColor
  3. {
  4. CGFloat red = arc4random() % 256 / 256.0;
  5. CGFloat green = arc4random() % 256 / 256.0;
  6. CGFloat blue = arc4random() % 256 / 256.0;
  7. return [UIColor colorWithRed:red green:green blue:blue alpha:1.0];
  8. }
  9. @end 

Method3-圆角矩形

2 给视图添加MotionEffect特效

#pragmamark-RoundRecttheImage-(UIImage*)roundedRectImageFromImage:(UIImage*)imagewithRadious:(CGFloat)radious{if(radious==0.0f)returnimage;if(image!=nil){CGFloatimageWidth=image.size.width;CGFloatimageHeight=image.size.height;CGRectrect=CGRectMake(0.0f,0.0f,imageWidth,imageHeight);UIWindow*window=[[[UIApplicationsharedApplication]windows]objectAtIndex:0];constCGFloatscale=window.screen.scale;UIGraphicsBeginImageContextWithOptions(rect.size,NO,scale);CGContextRefcontext=UIGraphicsGetCurrentContext();CGContextBeginPath(context);CGContextSaveGState(context);CGContextTranslateCTM(context,CGRectGetMinX(rect),CGRectGetMinY(rect));CGContextScaleCTM(context,radious,radious);CGFloatrectWidth=CGRectGetWidth(rect)/radious;CGFloatrectHeight=CGRectGetHeight(rect)/radious;CGContextMoveToPoint(context,rectWidth,rectHeight/2.0f);CGContextAddArcToPoint(context,rectWidth,rectHeight,rectWidth/2.0f,rectHeight,radious);CGContextAddArcToPoint(context,0.0f,rectHeight,0.0f,rectHeight/2.0f,radious);CGContextAddArcToPoint(context,0.0f,0.0f,rectWidth/2.0f,0.0f,radious);CGContextAddArcToPoint(context,rectWidth,0.0f,rectWidth,rectHeight/2.0f,radious);CGContextRestoreGState(context);CGContextClosePath(context);CGContextClip(context);[imagedrawInRect:CGRectMake(0.0f,0.0f,imageWidth,imageHeight)];UIImage*newImage=UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();returnnewImage;}returnnil;}

2.1 问题

UIMotionEffect是iOS7中新增加一个类,它能帮助开发者为用户界面加上运动拟真效果,本案例使用UIMotionEffect给视图添加MotionEffect特效,如图-2所示:

图片 3

图-2

本文由qg777发布于操作系统,转载请注明出处:Dynamic支持CollectionView布局 、 MotionEffects特效 、 BlurImage效果 、 TextKit

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。