iOS 滚动放大缩小

作者: 倚楼听风雨wing | 来源:发表于2016-07-12 15:47 被阅读1464次
滚动放大缩小.gif

简介##

效果:滚动到中间的时候最大,距离中间越远越小.
思路:实现这样的效果,我们首先要选对UI组件,这里我选择使用UICollectionView,而它的布局主要是依靠其flowLayout,所以我决定自定义FlowLayout实现该效果.

步骤##

自定义WYCollectionViewFlowLayout继承自UICollectionViewFlowLayout重写3个布局方法

@interface WYCollectionViewFlowLayout : UICollectionViewFlowLayout

@end

@implementation WYCollectionViewFlowLayout

// 这个方法返回所有的布局所需对象,瀑布流也可以重写这个方法实现.
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
    // 1.获取cell对应的attributes对象
    NSArray *arrayAttrs = [super layoutAttributesForElementsInRect:rect];
    
    // 2.计算整体的中心点的x值
    CGFloat centerX = self.collectionView.contentOffset.x + self.collectionView.bounds.size.width * 0.5;
    
    // 3.修改一下attributes对象
    for (UICollectionViewLayoutAttributes *attr in arrayAttrs) {
        // 3.1 计算每个cell的中心点距离
        CGFloat distance = ABS(attr.center.x - centerX);
        
        // 3.2 距离越大,缩放比越小,距离越小,缩放比越大
        CGFloat factor = 0.003;
        CGFloat scale = 1 / (1 + distance * factor);
        attr.transform = CGAffineTransformMakeScale(scale, scale);
    }
    return arrayAttrs;
}

// 当bounds发生改变的时候需要重新布局
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
    return true;
}

/// 滑动停止
///
/// @param proposedContentOffset 当手指滚动完毕后,自然情况下根据“惯性”,会停留的位置
/// @param velocity              速率,周率
///
/// @return 人为要让它停留的位置
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity {
    // 1.计算中心点位置
    CGFloat centerX = proposedContentOffset.x + self.collectionView.bounds.size.width * 0.5;
    
    // 2.计算可视化区域
    CGFloat visibleX = proposedContentOffset.x;
    CGFloat visibleY = proposedContentOffset.y;
    CGFloat visibleW = APP_WIDTH;
    CGFloat visibleH = self.collectionView.bounds.size.height;
    CGRect visibleRect = CGRectMake(visibleX, visibleY, visibleW, visibleH);
    
    // 3.获取可视区域的cell的attribute对象
    NSArray *attrs = [self layoutAttributesForElementsInRect:visibleRect];
    
    // 4.比较出最小的偏移
    int min_idx = 0;
    UICollectionViewLayoutAttributes *min_attr = attrs[min_idx];
    
    // 5.循环比较出最小的
    for (int i = 1; i< attrs.count; i++){
        // 5.1min_attr和中心点的距离
        CGFloat distance1 = ABS(min_attr.center.x - centerX);
        
        // 5.2当前循环的attr和中心点的距离
        UICollectionViewLayoutAttributes *currentAttr = attrs[i];
        CGFloat distance2 = ABS(currentAttr.center.x - centerX);
        
        if (distance2 < distance1) {
            min_idx = i;
            min_attr = currentAttr;
        }
    }
    // 6.计算出最小的偏移值
    CGFloat offsetX = min_attr.center.x - centerX;
    
    return CGPointMake(proposedContentOffset.x + offsetX, proposedContentOffset.y);
}

@end

然后在初始化UICollectionView的时候,设置其流水布局collectionViewLayout为我们自定义的WYCollectionViewFlowLayout即可实现滚动的放大缩小了.

相关文章

  • iOS 滚动放大缩小

    简介## 效果:滚动到中间的时候最大,距离中间越远越小.思路:实现这样的效果,我们首先要选对UI组件,这里我选择使...

  • Android 求教 仿bilibili长视频详情页和微博视频

    视频随滚动放大或缩小

  • 核心动画 - Core Animation

    我所知道的Core AnimationCore Animation负责所有的滚动、旋转、缩小和放大以及所有的iOS...

  • CoreAnimation

    Core Animation负责所有的滚动、旋转、缩小和放大以及所有的iOS动画效果。其中UIKit类通常都有an...

  • 基本操作 | AI从入门到精通

    1. 放大和缩小 方法1:视图 - 放大/缩小 方法2:Ctrl + +/- 方法3:Alt + 向上滚动鼠标滑轮...

  • Android开发banner上下滚动轮播

    一、效果图 banner一般不是左右滚动嘛?现在可以上下滚动,折叠滚动,放大缩小滚动等等具体可以看https://...

  • Mac - 触控板的使用

    一个手指的功能:左键二个手指的功能:右键、上下滚动、捏合放大缩小、轻点放大缩小、旋转、前进后退、三个手指的功能:上...

  • dagre-d3 项目实践

    功能包含: 鼠标滚动放大缩小 node节点click、hover、color设置 edge连线hover 动态添加...

  • 鼠标滚轮事件

    通过一个小例子来介绍鼠标的滚轮事件,通过鼠标向上滚动来放大图片,向下滚动来缩小图片下面是HTML文档 下面是封装的...

  • 222天--放大和缩小2022-08-21

    222天--放大和缩小2022-08-21 ?放大与缩小? 把困难放大,恩典缩小,你就是一个痛苦的人。 把恩典放大...

网友评论

  • 054ce4d15908:第一个和最后一个没有放大效果,也不能滚动到最后一个和第一个的位置,有没有方法解决,楼主,谢谢
    054ce4d15908:@倚楼听风雨wing 恩
    倚楼听风雨wing:只有滚动到中间才会放大,第一个和最后一个正常情况下是不能滚动到中间的,可是你可以设置collectionView的contentInset让第一个和最后一个都可以滚动到中间
  • SunnnyBoys:不错
  • 034a7d67ef05:如果要控制每次每个cell滑动的距离怎么做呢,大神
  • 背着吉他去流浪:来个GitHub地址吧

本文标题:iOS 滚动放大缩小

本文链接:https://www.haomeiwen.com/subject/syxsjttx.html