在UITableView中滚动时移动视图

paj*_*vic 26 cocoa-touch uitableview uiscrollview uiview ios

我有一个UIViewUITableView它下面:

在此输入图像描述

我想要做的是UITableView当用户开始在表格中滚动时,让上方的视图向上移动(不在路上),以便有更多空间UITableView(当你再次向下滚动时降下来).

我知道这通常是通过表头视图完成的,但我的问题是我的表视图位于一个选项卡内(实际上它是一个使用的侧滚动页面视图TTSliddingPageviewcontroller).所以虽然我只有一个顶部UIView有三个UITableView.

是否可以手动完成此操作?我的第一个想法是把所有东西放在一个UIScrollView,但根据Apple的文档,一个人不应该放在一个UITableView内部,UIScrollView因为这会导致不可预测的行为.

小智 25

Swift解决方案(与滚动视图启用弹跳功能完美配合):

 var oldContentOffset = CGPointZero
 let topConstraintRange = (CGFloat(120)..<CGFloat(300))

 func scrollViewDidScroll(scrollView: UIScrollView) {

    let delta =  scrollView.contentOffset.y - oldContentOffset.y

    //we compress the top view
    if delta > 0 && topConstraint.constant > topConstraintRange.start && scrollView.contentOffset.y > 0 {
        topConstraint.constant -= delta
        scrollView.contentOffset.y -= delta
    }

    //we expand the top view
    if delta < 0 && topConstraint.constant < topConstraintRange.end && scrollView.contentOffset.y < 0{
        topConstraint.constant -= delta
        scrollView.contentOffset.y -= delta
    }

    oldContentOffset = scrollView.contentOffset
 }
Run Code Online (Sandbox Code Playgroud)

  • 我们从哪里获得`topConstraint`? (2认同)

Nob*_*ica 19

由于UITableView是子类UIScrollView,您的表视图的委托可以接收UIScrollViewDelegate方法.

在表视图的委托中:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    static CGFloat previousOffset;
    CGRect rect = self.view.frame;
    rect.origin.y += previousOffset - scrollView.contentOffset.y;
    previousOffset = scrollView.contentOffset.y;
    self.view.frame = rect;
}
Run Code Online (Sandbox Code Playgroud)


Dvo*_*ole 9

Swift 3&4:

    var oldContentOffset = CGPoint.zero
    let topConstraintRange = (CGFloat(0)..<CGFloat(140))

    func scrollViewDidScroll(_ scrollView: UIScrollView) {

        let delta =  scrollView.contentOffset.y - oldContentOffset.y

        //we compress the top view
        if delta > 0 && yourConstraint.constant > topConstraintRange.lowerBound && scrollView.contentOffset.y > 0 {
            yourConstraint.constant -= delta
            scrollView.contentOffset.y -= delta
        }

        //we expand the top view
        if delta < 0 && yourConstraint.constant < topConstraintRange.upperBound && scrollView.contentOffset.y < 0{
            yourConstraint.constant -= delta
            scrollView.contentOffset.y -= delta
        }
        oldContentOffset = scrollView.contentOffset
    }
Run Code Online (Sandbox Code Playgroud)


Exc*_*ion 9

我在最后一个解决方案中添加了一些约束,以防止在快速滚动的情况下出现一些奇怪的行为

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let delta =  scrollView.contentOffset.y - oldContentOffset.y

    //we compress the top view
    if delta > 0 && topConstraint.constant > topConstraintRange.lowerBound && scrollView.contentOffset.y > 0 {
        searchHeaderTopConstraint.constant = max(topConstraintRange.lowerBound, topConstraint.constant - delta)
        scrollView.contentOffset.y -= delta
    }

    //we expand the top view
    if delta < 0 && topConstraint.constant < topConstraintRange.upperBound && scrollView.contentOffset.y < 0 {
        topConstraint.constant = min(searchHeaderTopConstraint.constant - delta, topConstraintRange.upperBound)
        scrollView.contentOffset.y -= delta
    }
    oldContentOffset = scrollView.contentOffset
}
Run Code Online (Sandbox Code Playgroud)


小智 8

更简单快捷的方法

- (void)scrollViewDidScroll:(UIScrollView *)scrollView 
{

    CGRect rect = self.view.frame;
    rect.origin.y =  -scrollView.contentOffset.y;
    self.view.frame = rect;

}
Run Code Online (Sandbox Code Playgroud)