项目中可能有这样一种需求,类似饿了么订单详情顶部那种渐变效果,偶然看到这个后,发现在项目中也可以用,所以就提议加上了这个功能,功能实现点非常简单,这里我不做理论方面的阐述,直接看重要代码即可:
先看下动图效果:
这里一般适用于滚动视图滚动,顶部改变的情形,需要监听滚动视图的contentOffset:
[_tableView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:NULL];
技术实现,需要拿到顶部视图的起始frame
以及终止frame
具体的变化控制如下:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if ([keyPath isEqualToString:@"contentOffset"]) {
CGPoint offset = [change[NSKeyValueChangeNewKey] CGPointValue];
if (offset.y <= 0) {
_topView.frame = CGRectMake(0, 0, self.view.frame.size.width, topHeight);
}else {
CGFloat scale = (topHeight - offset.y) / topHeight;
if (scale <= 0) {
scale = 0;
}
if (scale >= 1) {
scale = 1;
}
CGFloat height = topHeight - (1- scale) * (topHeight - _destHeight);
_topView.frame = CGRectMake(0, 0, self.view.frame.size.width, height);
_tableView.contentInset = UIEdgeInsetsMake(height, 0, 0, 0);
[_topView updateTopViewWithScale:scale];
}
}
}
这里主要控制topView的frame渐变,至于topView中的个别控件控制,这里以titleLabel为例:
- (void)updateTopViewWithScale:(CGFloat)scale {
CGPoint center = _titleLabel.center;
center.x = (_titleSourceCenter.x + (1-scale) * (_titleDestCenter.x - _titleSourceCenter.x));
center.y = _titleSourceCenter.y - (1-scale) * (_titleSourceCenter.y - _titleDestCenter.y);
_titleLabel.center = center;
CGFloat font = 18 * scale;
if (font < 15) {
font = 15;
}
_titleLabel.font = [UIFont systemFontOfSize:font];
[_titleLabel layoutIfNeeded];
}
只需要知道titleLabel
的起始
和终止
的center
,以及font
即可