如今主流app裏面常常須要有tableView上滑出現懸浮條樣式的設計,寶寶看了下appleStore裏面專題推薦用的scrollView 也有相似的懸浮效果,只不過它是下拉懸浮,而主流的是上滑懸浮!最終實現效果如如下gif圖。 app
其實一看上去 表覺得是兩種不一樣的方案,其實兩種思路方式徹底一致,原本核心代碼就一行,那麼要修改的代碼豈不是半行,確實如此哦,寶寶已笑瘋😂😂😂,好了啦,開個玩笑,進入正題! ##先別敲代碼,想一想懸浮條實現思路##代碼實現ide
- (void)viewDidLoad {
[super viewDidLoad];
//加載tableView到self.view上
UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 375, 667) style:UITableViewStylePlain];
[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];
tableView.dataSource = self;
tableView.contentInset = UIEdgeInsetsMake(200, 0, 0, 0);
[self.view addSubview:tableView];
//利用KVO監聽tableView的contentOffset的屬性值,從而動態改變懸浮條yellowView的frame值
[tableView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
//加載yellowView做爲懸浮條視圖到self.view上,所以tableView和yellowView是同一級關係,黃色視圖在tableView的上面
TouchView *yellowView = [[TouchView alloc] initWithFrame:CGRectMake(0, 0, 375, 200)];
yellowView.backgroundColor = [UIColor yellowColor];
//將alpha設置成爲0.7的透明度是爲了看得更清楚底下的tableView隨時滾動的位置
yellowView.alpha = 0.7;
[self.view addSubview:yellowView];
//設置成全局的實例變量是爲了在監聽方法中能夠改變懸浮條yellowView的frame值
_yellowView = yellowView;
}
#pragma mark - KVO監聽tableView的contentOffset的屬性值變化
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
CGPoint offset = [change[NSKeyValueChangeNewKey] CGPointValue];
//64爲懸浮條最終停留的高度
if (offset.y < -64) {
//小於-64則有兩種狀況,第一種小於-64是當懸浮條一進來時候,因爲contentInset.top被咱們調成了懸浮條的高度200,
所以offset.y初始值是-200,當用戶上滑懸浮條的時候,會在 -200 <= offset.y <= -64 範圍內波動,咱們須要
調整懸浮條的Y座標爲-offset.y - 200,如- (-180) - 200 = -20 ,表明tableView向上偏移了20各點,咱們改變其原點,
形成懸浮條懸停的假象;第二種小於-64是當懸浮條一進來時候,offset.y初始值是-200,當用戶下滑懸浮條的時候,offset.y會負的越多,
在 offset.y < -200 範圍內波動,咱們須要調整懸浮條的Y座標爲固定值200,不讓其變大變小便可!!搞定
//第一種方案,改變懸浮條的Y座標,而不改變其高度,這也是本文核心代碼!!!!
_yellowView.frame = offset.y <= -200 ? CGRectMake(0, 0, 375, 200) : CGRectMake(0, -offset.y - 200, 375, 200);
//第二種方案,改變懸浮條的高度,而不改變其原點
//_yellowView.frame = offset.y < -200 ? CGRectMake(0, 0, 375, 200) : CGRectMake(0, 0, 375, -offset.y);
//下面這行代碼不必添加,我看到網上不少人加了這句,實屬不必,tableView滾動原本就靠contentOffset,contentInset只是添加額外的滾動區域的
//_tableView.contentInset = offset.y > -200 ? UIEdgeInsetsMake(-offset.y, 0, 0, 0) :UIEdgeInsetsMake(200, 0, 0, 0);
}else {
//大於等於-64就只有一種狀況了,當到達臨界值的時候就會 懸停64的最小高度,該高度本身隨便寫啦,而後appStore那個效果是上滑到臨界值後,高度依然減少,
那麼須要調整懸浮條的Y座標爲-offset.y - 200,offset.y會愈來愈 大於-64,致使_yellowView.frame.origin.y負的越多,越來偏離屏幕原點,
正好知足需求看不見懸浮條啦!
//appStore下拉懸浮條效果只須要改這行代碼讓上滑的時候原點超過其高度200,這樣就看不到懸浮條了
//_yellowView.frame = CGRectMake(0, -offset.y - 200, 375, 200);;
//第一種方案,改變懸浮條的Y座標爲懸停最小值64 - 200,這樣在用戶界面上就只顯示64的高度,而不改變其高度
_yellowView.frame = CGRectMake(0, 64 - 200, 375, 200);
//第二種方案,改變懸浮條的高度爲最小值64,而不改變其原點
//_yellowView.frame = CGRectMake(0, 0, 375, 64);
//下面這行代碼不必添加,我看到網上不少人加了這句,實屬不必,tableView滾動原本就靠contentOffset,contentInset只是添加額外的滾動區域的
//_tableView.contentInset = UIEdgeInsetsMake(64, 0, 0, 0);
}
}
複製代碼
###自定義TouchView 若是有另外需求好比要是拖動黃色視圖,tableView要是也能滾動的話,那麼就須要本身攔截點擊事件!!spa
@implementation TouchView
//這兩個方法隨便寫一個便可,爲的是攔截響應鏈,不讓其捕獲到觸摸事件,這樣用戶手指點擊上面的黃色視圖,window分發觸摸事件的時候,會認爲用戶點擊的那個點最遠的響應視圖是 tableView,由於tableView在黃色視圖的下方,這樣,當滑動黃色視圖的時候,tableView也跟着一塊兒滾動了啦!!!
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
return NO;
}
//先調用hitTest:withEvent:此方法,再調用pointInside:withEvent:
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView *view = [super hitTest:point withEvent:event];
if ([view isKindOfClass:[self class]]) {
return nil;
}
return nil;
}
@end
複製代碼