tableView视差滚动
2016-01-29 00:00
393 查看
摘要: 当tableView滚动时,cell中的图片会上下微移(相对于cell本身),在视觉上给人一种透过窗户看屋内事物的视觉差错感。具体实现详见正文。
code:
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的内省(Introspection)用法小结
- Objective-C中常用的结构体NSRange,NSPoint,NSSize(CGSize),NSRect实例分析
- Objective-C中使用NSString类操作字符串的方法小结
- Objective-C中NSNumber与NSDictionary的用法简介
- JavaFX之TableView的使用详解
- Objective-C中NSLog输出格式大全
- 全面解析Objective-C中的block代码块的使用
- Swift调用Objective-C编写的API实例
- Swift、Objective-C、Cocoa混合编程设置指南
- Objective-c代码如何移植为Swift代码 Objective-c代码转移到Swift过程介绍
- Swift调用Objective-C代码
- 以实例讲解Objective-C中的KVO与KVC机制
- 简介Objective-C解析XML与JSON数据格式的方法
- 理解Objective-C的变量以及面相对象的继承特性
- 简单讲解Objective-C的基本特性及其内存管理方式
- tableView上面空出20个像素的解决办法
- Objective-C处理空字符串和页面传值及自定义拷贝
- objective-c中生成随机数的方法
- 在Swift中使用Objective-C编写类、继承Objective-C类
- Swift能代替Objective-C吗?