UIDynamicAnimator 结合 CollectionViewControllerLayout

UIDynamicAnimator 结合 CollectionViewControllerLayout——方法

05 View ▸ day10 ▸ Demo1_CollectionView_Dynamic
1. UIDynamicAnimator 结合 CollectionViewControllerLayout
WWDC2013  Session

[Demo1]

UICollectionViewLayout 
是抽象类, 继承此类需要在子类中做大量的工作(覆盖大量的方法)
UICollectionViewFlowLayout
UICollectionViewLayout类的子类,是一个具体的实现类,提供流式的布局管理。如果继承此类,我们只需要覆盖掉我们自己需要的方法

2.
模糊效果
iOS7大量效果的设计
UIImage+ImageEffects类

3. MotionEffects效果


UIMotionEffect类是抽象类,是所有MotionEffect特效类的父类

UIInterpolatingMotionEffect 是他的一个常见的子类
   UIMotionEffectGroup 
也是他的一个子类,此类可以将多个特效对象合并成一个特效对象,然后加入到视图上





UIDynamicAnimator 结合 CollectionViewControllerLayout——使用

Map

纯代码:

1.在ViewDidLoad中
// 创建 collectionView 指定大小且自定义布局
    UICollectionView *collectionView = [[UICollectionView alloc]initWithFrame:self.view.frame collectionViewLayout:layout];

2.new一个自定义类,TRCollectionViewSpringCellLayout继承自 UICollectionViewFlowLayout

3.在ViewDidLoad中
// 创建布局
TRCollectionViewSpringCellLayout *layout = [[TRCollectionViewSpringCellLayout alloc]init];
4.添加到view
[ self . view addSubview :collectionView];
5.设置数据源,遵守协议 < UICollectionViewDataSource >,回答问题
定义:static NSString *cellIdentifier = @"MyCell" ;
在ViewDidLoad中
// 设置数据源
    collectionView.dataSource = self;
// 注册cell
    [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:cellIdentifier];
// 遵守了协议,回答 3 个问题(分区,行,数据)
- (
NSInteger )collectionView:( UICollectionView *)collectionView numberOfItemsInSection:( NSInteger )section
{
   
return 50 ;
}

- (
UICollectionViewCell *)collectionView:( UICollectionView *)collectionView cellForItemAtIndexPath:( NSIndexPath *)indexPath
{
    // 拿到 cell
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier : cellIdentifier forIndexPath :indexPath];
    //[UIColor randomColor] 随机颜色 因为没有这个方法,我们要创建一个RandomColor类继承自UIColor
    cell. backgroundColor = [ UIColor randomColor ];
   
return cell;
}
6.给类加方法Objective-C category
[
--------实现随机有2种方式,一种:添加UIColor类方法(分类:可以给某一个类扩充一些方法),一种直接实现方法--------
方法一(xcode6)添加分类:
方法二:
]
声明(公有): + ( UIColor *)randomColor;
实现:
+ ( UIColor *)randomColor
{
    CGFloat red = arc4random () % 256 / 255.0 ;
   
CGFloat green = arc4random () % 256 / 255.0 ;
   
CGFloat blue = arc4random () % 256 / 255.0 ;
    return [UIColor colorWithRed:red green:green blue:blue alpha:1.0];
}
7.可以设置布局的属性
layout. itemSize = CGSizeMake ( 300 , 40 );//宽度 高度
layout.sectionInset = UIEdgeInsetsMake(0, 10, 0, 10);
8.此时翻的时候有滚动条,我们可以把它关闭
// 关闭滚动条
    collectionView.
showsVerticalScrollIndicator = NO ;
    collectionView.showsHorizontalScrollIndicator = NO;

接下来就要设置动画效果
9.定义私有的动画属性
@interface TRCollectionViewSpringCellLayout ()
@property ( strong , nonatomic ) UIDynamicAnimator *animator;
@end
10.实现(给每个cell添加一个 AttachmentBehavior[吸附行为]
// 布局前的准备,布局开始前自动调用
- (
void )prepareLayout
{
   
// 给每个一 Cell 创建 UIAttachmentBehavior( 吸附行为 )
   
if (! self . animator ){
       
//UIDynamicAnimator 专门针对 CollectionView 布局的方法
       
self . animator = [[ UIDynamicAnimator alloc ] initWithCollectionViewLayout : self ];
       
// 总共内容的大小(所有的 cell
       
CGSize contentSize = [ self collectionViewContentSize ];
       
//[super layoutAttributesForElementsInRect ..] 拿到一个 Rect 范围内的所有的 cell 的布局属性
       
NSArray *items = [ super layoutAttributesForElementsInRect : CGRectMake ( 0 , 0 , contentSize. width , contentSize. height )];
       
// 遍历
       
for ( UICollectionViewLayoutAttributes *attributes in items) {
           
// 创建吸附行为
           
UIAttachmentBehavior *spring = [[ UIAttachmentBehavior alloc ] initWithItem :attributes attachedToAnchor :attributes. center ];
            spring.
damping = 0.6 ; // 阻尼
            spring.
frequency = 0.8 ; // 频率
            [
self . animator addBehavior :spring];
        }
    }
}
11.覆盖布局
// 返回在 rect 范围内的布局属性
- (
NSArray *)layoutAttributesForElementsInRect:( CGRect )rect
{
   
// 返回每个 Cell 的布局属性
   
return [ self . animator itemsInRect :rect];
}
// 专门针对 UICollectionViewLayout ,第几个区的第几个 item (每个 cell 的布局)
- (
UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:( NSIndexPath *)indexPath
{
   
return [ self . animator layoutAttributesForCellAtIndexPath :indexPath];
}
12.达到弹簧效果
// bounds 发生变化时 , 调用方法 , 为不同的 Cell 改变不同的锚点
- (
BOOL )shouldInvalidateLayoutForBoundsChange:( CGRect )newBounds
{
   
// 拿出 collectionView
   
UIScrollView *scrollView = self . collectionView ;
   
// 获取滚动的距离
   
CGFloat scrollDelta = newBounds. origin . y - scrollView. bounds . origin . y ;
   
// 手指所在的位置
   
CGPoint touchLocation = [scrollView. panGestureRecognizer locationInView :scrollView];
   
// 计算和改动每一个 Cell 的锚点
   
// 遍历所有的行为
   
for ( UIAttachmentBehavior *spring in self . animator . behaviors ) {
       
// Attributes Behavior 去拿绑定的 item
       
UICollectionViewLayoutAttributes *item = [spring. items firstObject ];
       
// 拿出中心点
       
CGPoint center = item. center ;
       
// 拿到 spring 的锚点
       
CGPoint anchorPoint = spring. anchorPoint ;
       
// 拿到距离   (用户点击的位置 - 锚点)
       
CGFloat distance = fabsf (touchLocation. y - anchorPoint. y );
       
// 阻力值
       
CGFloat scrollResistance = distance / 800 ;
       
// 滚动距离 >0?( 距离,距离 * 阻力值 当中取一个最小值 )
        center.
y += (scrollDelta> 0 )? MIN (scrollDelta, scrollDelta * scrollResistance): MAX (scrollDelta, scrollDelta * scrollResistance);
       
// 把中心点赋值回去
        item.
center = center;
       
// item 处于动画中时 , 如果对象主动修改了位置信息, 需要更新动画
        [
self . animator updateItemUsingCurrentState :item];
    }
   
return NO ; // 要不要重新计算边界
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值