UIScrollView 半屏滚动效果

引言:

对于滚动型的半屏滚动,由于 PagEnable 打开以后只能根据滚动视图本身的高宽进行按页滚动,实现原理主要是调用 DidScroll 代理方法,对内容进行跟踪滚动,可以实现任意距离跟踪滚动.


# 一. 效果

# 二. 代码逻辑

# LCScrollView.h文件:

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface LCScrollView : UIScrollView
@property (nonatomic, strong) NSArray *images;
@end

NS_ASSUME_NONNULL_END

# LCScrollView.m文件:

#import "LCScrollView.h"
#define rateDistance 380

@interface LCScrollView () <UIScrollViewDelegate>

@property (nonatomic, assign) CGFloat moverate;
@property (nonatomic, strong) NSMutableArray *ImageXarr;
@property (nonatomic, assign) CGFloat moveNum;
@end

@implementation LCScrollView

// 
- (instancetype)initWithFrame:(CGRect)frame {
    
    self = [super initWithFrame:frame];
    if (self) {
        self.delegate = self;
        self.contentOffset = CGPointMake(0, 0);
        
    }
    return self;
}


-(void)setImages:(NSArray *)images {
    
    _images = [NSArray arrayWithArray:images];
    [self creatMainview];
}


-(void)creatMainview {
    
    self.contentSize = CGSizeMake(self.frame.size.width * _images.count, self.frame.size.height);
    self.moverate = 0;
    NSLog(@"%lu",(unsigned long)_images.count);
    self.pagingEnabled = YES;
    self.showsHorizontalScrollIndicator = NO;
    self.showsVerticalScrollIndicator = NO;
    [self SetImagerView];
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    UITouch * evt = [touches anyObject];
    CGPoint point = [evt locationInView:self];
    CGFloat wide = self.frame.size.width;
    CGFloat x1 = self.contentOffset.x + wide;
    CGFloat x2 = self.contentOffset.x - wide;
    if(point.x - self.moverate >= self.frame.size.width * 0.79 && point.x < self.frame.size.width * 7)
    {
        [UIView animateWithDuration:0.2 animations:^{
            self.contentOffset = CGPointMake(x1, 0);
            [self scrollViewDidScroll:self];
        } completion:^(BOOL finished) {
        }];
    }
    else if(point.x - self.moverate <= self.frame.size.width * 0.21 && point.x > self.frame.size.width*0.25)
    {
        [UIView animateWithDuration:0.2 animations:^{
            self.contentOffset = CGPointMake(x2, 0);
            [self scrollViewDidScroll:self];
        } completion:^(BOOL finished) {
            
        }];
    }
    
    [self scrollViewDidScroll:self];
}

- (void)SetImagerView {
    
    self.ImageXarr = [[NSMutableArray alloc]init];
    
    for (int i = 0 ; i < self.images.count; i++) {
        
        CGRect make = CGRectMake(self.frame.size.width / _images.count * i, 0, self.frame.size.width * 0.6  , self.frame.size.width * 0.5);
        
        UIImageView * imageView = [[UIImageView alloc]initWithFrame:make];
        imageView.center = CGPointMake((self.frame.size.width*0.6)/2 * (2 * i + 1.67) , self.frame.size.height/2.0);
        //设置背景
        CALayer * layer = [imageView layer];
        layer.shadowColor = [[UIColor blackColor]CGColor];
        layer.shadowOffset = CGSizeMake(10, 5);
        layer.shadowRadius = 10;
        layer.shadowOpacity = 0.5;
        
        imageView.backgroundColor = [UIColor redColor];
        imageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"img_%d",i]];
        imageView.tag = i + 100;

        [self addSubview:imageView];
    };
    
    [self scrollViewDidScroll:self];
}

-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGFloat rate;
    CGFloat reduce;
    
    reduce = self.moverate - scrollView.contentOffset.x;
    
    self.moveNum += reduce;
    //NSLog(@"%f",reduce);
    for (int i = 0 ; i < _images.count; i++) {
        
        UIView * view = [self viewWithTag:100 + i];
        CGFloat distance = fabs(scrollView.contentOffset.x + self.frame.size.width/2  - view.center.x);
        
        CGFloat ratex = view.center.x - reduce * 0.4;
        
        view.center = CGPointMake(ratex,view.center.y);
        
        if (distance >= rateDistance)
            rate = 0.7;
        else
            rate =  (rateDistance - distance*0.2) / (rateDistance ) ;
        
        view.transform = CGAffineTransformMakeScale(rate, rate);
    }
    self.moverate = scrollView.contentOffset.x;
    
}