iOS scrollview循环播放加缩放

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS scrollview循环播放加缩放相关的知识,希望对你有一定的参考价值。

  前些日子一直在研究3d的框架没有时间写博客,不过最后需求改了,也没研究出个啥。这段时间出了新的需求,需要循环播放图片,并且滑动的时候中间的图片有缩放的效果。刚开始想在网上搜索,不过并没有找到合适的demo,没办法只能写个了。

  首先说下思路,做这个效果需要解决三个问题。

  第一个问题,如何控制每次滑动的距离。ios中好像并没有设置scrollview每次滑动的距离吧。设置其画框的大小和pageenable的时候已经决定了其每次滑动的距离。但是需求要显示三张图片啊,中间大图,两边的图片只显示一部分。也是想了个恶心的办法,将画框的大小设置成图片的宽度?一个图片之间的距离(这个距离可根据实际情况调整),将masktobounds设置为no,即可。不过这样做有一个缺点,左右两边的图片是不能响应滑动事件的,以后有时间再解决这个问题吧。

  第二个问题,循环播放,这个估计都会,不解释了,可以看代码。

  第三个问题,也是难点,如何在滑动的时候改变图片的大小。我们可以根据图片在scrollview上的位置得到其centerx,然后根据其与contentoffset.x+width/2.0(图片的宽度一半)+gap/2.0(图片间距的一半)之间的差作为x,构建一次线性方程式,其实很简单,看看代码就懂了。最后设置transform。

  可能说的不清楚,直接上代码吧。

  1 //图片的个数
  2 #define ARRAYCOUNT 3
  3 //缩放的比例
  4 #define SCALE 0.369565
  5 #import "ALNewKeeperScrollView.h"
  6 #import "ALNewKeeperModelView.h"
  7 
  8 @interface ALNewKeeperScrollView ()<UIScrollViewDelegate>
  9 {
 10     float rate;
 11     float gap;
 12     float whRate;
 13     float width ;
 14     float height;
 15     BOOL ifFirstScroll;
 16 }
 17 @property (nonatomic, strong) UIScrollView *scrollView;
 18 @end
 19 
 20 @implementation ALNewKeeperScrollView
 21 
 22 - (instancetype)initWithFrame:(CGRect)frame
 23 {
 24     if (self = [super initWithFrame:frame])
 25     {
 26         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setClipsToBoundsYes) name:@"setClipsToBoundsYes" object:nil];
 27         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setClipsToBoundsNo) name:@"setClipsToBoundsNo" object:nil];
 28         rate = 640/SCREEN_WIDTH;
 29         gap = (28*4)/rate;
 30         whRate = (float)630/470;
 31         height = 460/rate;
 32         width = height/whRate;
 33         
 34         self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, width+gap, self.height)];
 35 //        self.scrollView.backgroundColor = [UIColor cyanColor];
 36         self.scrollView.centerX = self.width*0.5;
 37         self.scrollView.showsVerticalScrollIndicator = NO;
 38         self.scrollView.showsHorizontalScrollIndicator = NO;
 39         self.scrollView.scrollsToTop = NO;
 40         self.scrollView.delegate = self;
 41         self.scrollView.clipsToBounds = NO;
 42         [self addSubview:self.scrollView];
 43         
 44         ifFirstScroll = YES;
 45     }
 46     return self;
 47 }
 48 - (void)setClipsToBoundsYes
 49 {
 50     self.scrollView.clipsToBounds = YES;
 51 }
 52 - (void)setClipsToBoundsNo
 53 {
 54     self.scrollView.clipsToBounds = NO;
 55 }
 56 - (void)config:(NSArray *)array andOffSet:(NSInteger)index
 57 {
 58     int arrayCount = ARRAYCOUNT;
 59     int count = arrayCount+4;
 60     for (int i=0; i<count; i++)
 61     {
 62         //3 4 0 1 2 3 4 0 1
 63         ALNewKeeperModelView *view = [[ALNewKeeperModelView alloc] initWithFrame:CGRectMake(gap/2.0 + i*(width+gap), 122/rate, width, height)];
 64         view.centerY = self.height * 0.5;
 65         if (i<2)
 66         {
 67             [view config:[NSString stringWithFormat:@"%i", i+3]];
 68         }
 69         else if (i<count-2)
 70         {
 71             [view config:[NSString stringWithFormat:@"%i", i-2]];
 72         }
 73         else
 74         {
 75             [view config:[NSString stringWithFormat:@"%i", i-(count-2)]];
 76         }
 77         [self.scrollView addSubview:view];
 78     }
 79     self.scrollView.pagingEnabled = YES;
 80 //    self.scrollView.bounces = NO;
 81     [self.scrollView setContentSize:CGSizeMake(count*(gap+width)+gap, 0)];
 82     float offsetx = (index+2)*(width+gap);
 83     [self.scrollView setContentOffset:CGPointMake(offsetx, 0)];
 84 }
 85 
 86 - (void)scrollViewDidScroll:(UIScrollView *)scrollView
 87 {
 88     CGFloat startX = width+gap;
 89     CGFloat endX = (ARRAYCOUNT + 2)*(width+gap);
 90     CGFloat offsetX = scrollView.contentOffset.x;
 91     if ((NSInteger)offsetX <= (NSInteger)startX )
 92     {
 93         [scrollView setContentOffset:CGPointMake(endX-startX, 0)];
 94     }
 95     if ((NSInteger)offsetX >= (NSInteger)endX)
 96     {
 97         [scrollView setContentOffset:CGPointMake(startX+startX, 0)];
 98     }
 99     //滑动的时候缩放图片大小
100     float contentOffsetX = scrollView.contentOffset.x;
101     float centerX = contentOffsetX+gap/2.0+width/2.0;
102     for (id view in [scrollView subviews])
103     {
104         if ([view isKindOfClass:[ALNewKeeperModelView class]])
105         {
106             ALNewKeeperModelView *modelView = (ALNewKeeperModelView *)view;
107             float x = modelView.centerX-centerX;
108             float scale = 1.0;
109             if (x >= 0 && x <= width)
110             {
111                 scale += -SCALE/width*x+SCALE;
112             }
113             else if (x < 0 && x > - width)
114             {
115                 scale += SCALE/width*x+SCALE;
116             }
117             NSLog(@"%f", scale);
118             [self setShadow:modelView andScale:scale];
119             modelView.transform = CGAffineTransformMakeScale(scale, scale);
120         }
121     }
122 }
123 
124 - (void)setShadow:(UIView *)view andScale:(float)scale
125 {
126     view.layer.shadowColor = [UIColor blackColor].CGColor;
127     view.layer.shadowOffset = CGSizeMake(4, 4);
128     view.layer.shadowRadius = 5;
129     view.layer.shadowOpacity = (float)(scale-1.0)*2;
130 }
131 
132 @end

  上述是主要的类,还有几个类就不用写了。可以将该类中没有的类自定义一个view进行替换。

以上是关于iOS scrollview循环播放加缩放的主要内容,如果未能解决你的问题,请参考以下文章

iOS transform解决连续多次旋转缩放,实现图片旋转缩放效果

iOS_7_scrollView大图缩放

iOS 7 缩放不能在具有 AutoLayout 的 ScrollView 中工作,但在 iOS8/9 中工作

如何在滚动视图中设置谷歌地图片段

嵌套的 ScrollView - 缩放后无法滚动到新照片

React Native scrollview 循环播放