tableView视差滚动

code:

//
//  SHParallaxCell.m
//  tableView视差滚动
//
//  Created by 邵瑞波 on 16/1/28.
//  Copyright © 2016年 邵瑞波. All rights reserved.
//

#import "SHParallaxCell.h"
#import "Masonry.h"

/*
    简化版中,scrollView 不是必须的。
 */

@interface SHParallaxCell()
@property (nonatomic, strong) UIScrollView *scrollView;  // 视差容器视图
@property (nonatomic, strong) UIImageView *imgView;      // 视图`图片展示`视图
@property (nonatomic, weak) UITableView *tableView;      // 父视图 tableView
@end

@implementation SHParallaxCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    
    if (self) {
        [self setupUI];
    }
    
    return self;
}

- (void)awakeFromNib {
    // Initialization code
    
    [self setupUI];
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

- (void)layoutSubviews {
    [super layoutSubviews];
    
    // 约束
}

// 记录 父视图 tableView
- (void)willMoveToSuperview:(UIView *)newSuperview {
    
    //NSLog(@"newSuperview=[%@]", newSuperview);
    
    UIView *view = newSuperview;
    
    // 查找 tableView
    while (view) {
        if ([view isKindOfClass:[UITableView class]]) {
            self.tableView = (UITableView *)view;
            // 添加 kvo 监听
            [self.tableView addObserver:self
                             forKeyPath:@"contentOffset"
                                options:NSKeyValueObservingOptionNew
                                context:nil];
            break;
        } else {
            view = view.superview;
        }
    }
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
//    NSLog(@"object=[%@]", object);
//    NSLog(@"cell.frame=[%@], change[@\"new\"]=[%@]", NSStringFromCGRect(self.frame) , change[@"new"]);
    
    CGPoint offSet = [change[@"new"] CGPointValue];
    CGFloat height = self.scrollView.bounds.size.height;
    
    offSet.y += height;
    CGFloat detal = offSet.y - self.frame.origin.y;
    CGFloat a = detal / height * 20.0;
    
    // 如果性能不行,这里可以考虑 `主线程异步`
    [self.imgView updateConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(self.scrollView.centerY).offset(a);
    }];
    
//    dispatch_async(dispatch_get_main_queue(), ^{
//        // 如果性能不行,这里可以考虑 `主线程异步`
//        [self.imgView updateConstraints:^(MASConstraintMaker *make) {
//            make.centerY.equalTo(self.scrollView.centerY).offset(a);
//        }];
//    });
}

// 设置 image
- (void)setImage:(UIImage *)image {
    if (!(self.imgView.image == image)) {
        self.imgView.image = image;
    }
}

#pragma mark - 初始化设置

- (void)setupUI {
    self.selectionStyle = UITableViewCellSelectionStyleNone;
    [self.contentView addSubview:self.scrollView];
    
    // 约束
    [self.contentView makeConstraints:^(MASConstraintMaker *make) {
        make.width.equalTo(self);
        make.height.equalTo(200);
    }];
    
    [self.scrollView makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.contentView).offset(8);
        make.left.equalTo(self.contentView).offset(8);
        make.right.equalTo(self.contentView).offset(-8);
        make.bottom.equalTo(self.contentView).offset(-8);
    }];
    
    [self.imgView makeConstraints:^(MASConstraintMaker *make) {
//        make.center.equalTo(self.scrollView);
        make.centerX.equalTo(self.scrollView.centerX);
        make.centerY.equalTo(self.scrollView.centerY);
        make.width.equalTo(self.scrollView);
        make.height.equalTo(240);
        
        self.scrollView.contentSize = CGSizeMake(0, 240);
    }];
    
    /*
        内容视图大小的size的高度为 200、image的高度为240、
        计算: 
            上下方的滚动范围均为 20
     */
}

#pragma mark - 懒加载控件

- (UIScrollView *)scrollView {
    if (!_scrollView) {
        _scrollView = [[UIScrollView alloc] init];
        
        _scrollView.userInteractionEnabled = NO;
        _scrollView.showsVerticalScrollIndicator = NO;
        _scrollView.showsHorizontalScrollIndicator = NO;
        _scrollView.bounces = NO;
        _scrollView.backgroundColor = [UIColor whiteColor];
        _scrollView.layer.cornerRadius = 8;
        _scrollView.clipsToBounds = YES;
        
        [_scrollView addSubview:self.imgView];
    }
    return _scrollView;
}

- (UIImageView *)imgView {
    if (!_imgView) {
        _imgView = [[UIImageView alloc] init];
        _imgView.contentMode = UIViewContentModeScaleAspectFill;  // 填充模式
//        _imgView.backgroundColor = [UIColor cyanColor];
    }
    return _imgView;
}

#pragma mark - 销毁 kvo 监听,否则会崩溃

- (void)dealloc {
    [self.tableView removeObserver:self forKeyPath:@"contentOffset"];
}

@end


你可能感兴趣的:(Objective-C,tableview,视差效果)