悬停在tableview上的搜索栏,cell太少的情况下会发生滑动冲突

有这样一个需求如图所示:
图片描述

绿色是navigation,高64,红色是一个搜索栏,高44,黄色是一个tableview
约束是红色top距离self.view的top 64 约束名称为:

self.searchBarTopConstraint

由于使用PureLayout,距离(64)可以用下面名称:

self.searchBarTopConstraint.constant

取到

黄色table的top距离红色bottom 0

现在要求:
1.黄色table上滑时红色随黄色上移直到完全被绿色遮盖。
2.黄色table下滑时红色随黄色下移直到回到状态1的位置。
注:
黄色下滑后在任何时候上滑皆会触发要求1
黄色上滑后在任何时候下滑皆会触发要求2

关键代码如下:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGFloat newPoint = scrollView.contentOffset.y;
    CGFloat changePoint = self.oldPoint - newPoint;
    if (changePoint < 0) {
        NSLog(@"上滑");
        if ((self.stopScroll && self.scrollUp) || !self.stopScroll) {
            self.scrollUp = YES;
            if (self.searchBarTopConstraint.constant > 20) {
                //self.searchBarTopConstraint.constant > 20 意思是当搜索框没有完全被上面高64的navigation盖住时(searchBar高44,所以64-44=20)
                self.searchBarTopConstraint.constant += changePoint;
            } else if (self.searchBarTopConstraint.constant <= 20) {
                self.searchBarTopConstraint.constant = 20;
            }
        }
    } else if (changePoint > 0){
        NSLog(@"下滑");
        if ((self.stopScroll && !self.scrollUp) || !self.stopScroll) {
            self.scrollUp = NO;
            if (self.searchBarTopConstraint.constant<64) {
                //self.searchBarTopConstraint.constant < 64 意思是当搜索框没有完全脱离navigation时
                self.searchBarTopConstraint.constant += changePoint;
            } else if (self.searchBarTopConstraint.constant >= 64) {
                self.searchBarTopConstraint.constant = 64;
            }
        }
        
    }
    self.oldPoint = newPoint;
    
}

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{
    self.stopScroll = YES;
}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    self.stopScroll = NO;
    [self.searchController.searchBar endEditing:YES];
}

问题:在cell数量足够的情况下比较正常(但不太平滑),不过在cell数量不满一个屏幕时会造成无法滑动的情况,究其原因是在此情况下向上滑动后不知为何会立刻向下滑动,不知怎么解决,求赐教。

阅读 3.9k
2 个回答

viewDidLoad里设置:

self.automaticallyAdjustsScrollViewInsets = NO;
[self.tableView setContentInset:UIEdgeInsetsMake(44, 0, 0, 0)]; // 使top view 不遮住table view

因为设置了content inset 的原因, 一开始的content offset y 是-44。

#pragma mark - UIScrollViewDelegate

-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGFloat y = scrollView.contentOffset.y;
    
    NSLog(@"y:%f", y);
    //判断上下滑
    if ([scrollView.panGestureRecognizer translationInView:scrollView.superview].y > 0) {
        // handle dragging to the down
        NSLog(@"down");
        [UIView animateWithDuration:0.2 animations:^{
            self.searchBarTopConstraint.constant = 64;
            [self.view layoutIfNeeded];
        }];
    }
    else {
        // handle dragging to the up
        NSLog(@"up");
        if (y > -44) {
            CGFloat constant = 64 - y - 44;
            
            if (constant > 20) {
                self.searchBarTopConstraint.constant = constant;
            }
            else {
                [UIView animateWithDuration:0.2 animations:^{
                    self.searchBarTopConstraint.constant = 20;
                    [self.view layoutIfNeeded];
                }];
            }
        }
        else {
            self.searchBarTopConstraint.constant = 64;
        }
    }
}

-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    self.stopScroll = NO;
}

-(void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
    self.stopScroll = YES;
    CGFloat y = scrollView.contentOffset.y;

    // 结束时,如果top view 显示了一部分,设为显示。通过设置table view 的 contentOffset,scrollViewDidScroll里self.stopScroll = YES 条件下会设置top view 的位置
    if (y >= -44 && y <= 0) {
        [self.tableView setContentOffset:CGPointMake(0, -44) animated:YES];
    }
}

做成组头就自带悬浮效果

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题