滚动 UITableView 时如何创建 NSLayoutConstraint

Posted

技术标签:

【中文标题】滚动 UITableView 时如何创建 NSLayoutConstraint【英文标题】:How create NSLayoutConstraint when scrolling UITableView 【发布时间】:2016-08-01 12:11:39 【问题描述】:

我在 SingleView 上有 UITableView。表格视图有约束左0,右0,底部0,顶部520。向上滚动时我需要将顶部520更改为0,向下滚动时返回520。如何做到这一点。 如何从滚动中更改NSLayoutConstraint -

- (void)scrollViewDidScroll:(UIScrollView *)scrollView

我试图实现这样但失败了

 - (void)scrollViewDidScroll:(UIScrollView *)scrollView

    if (scrollView.tag == 1)

        if (scrollView.contentOffset.y < pointNow.y) 

            self.heightLogTabTableView.constant = 0;

            [UIView animateWithDuration:0.5f animations:^
                [self.view layoutIfNeeded];
            ];

        else if (scrollView.contentOffset.y > pointNow.y) 

            self.heightLogTabTableView.constant = 520;
            [UIView animateWithDuration:0.5f animations:^
                [self.view layoutIfNeeded];
            ];
        
    

【问题讨论】:

创建一个 TopSpace 约束的出口,并根据需要更改其在 scrollView 委托中的常量值。 相反,使用 indexPath 跟踪 willDisplayCellCellForRowAtIndexPath 代表中的滚动,并根据行或部分执行适当的操作 @NSNoob UITableView 继承自 UIScrollView 这意味着 UIScollView 的委托方法应该可以工作 @NSNoob scrollView 父表视图,我认为实现这一点。 【参考方案1】:

将代码中的[self.view layoutIfNeeded]; 替换为-- [_tableView beginUpdates];[_tableView endUpdates];。同时修改你的变量 pointNow 如下。

#import "ViewController.h"

@interface ViewController (UIScrollViewDelegate)




@end

@implementation ViewController
CGPoint pointNow;

- (void)viewDidLoad

     [super viewDidLoad];   
     pointNow = CGPointMake(0, 0);



- (void)scrollViewDidScroll:(UIScrollView *)scrollView



        if (scrollView.contentOffset.y < pointNow.y) 

            self.heightLogTabTableView.constant = 0;

            [UIView animateWithDuration:0.5f animations:^
                [_tableView beginUpdates];
                [_tableView endUpdates];
            ];

        else if (scrollView.contentOffset.y > pointNow.y) 

            self.heightLogTabTableView.constant = 520;
            [UIView animateWithDuration:0.5f animations:^
                [_tableView beginUpdates];
                [_tableView endUpdates];
            ];
        
    pointNow = scrollView.contentOffset;



@end

【讨论】:

【参考方案2】:

在更改约束常量后立即尝试 setNeedsUpdateConstraints 方法。喜欢:

[self.tableView setNeedsUpdateConstraints];

更新 -

如果我理解正确,我认为这就是你要找的:

-(void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset

    if(self.heightLogTabTableView.contentOffset.y<0)
        //it means table view is pulled down like refresh
    
    else if(self.heightLogTabTableView.contentOffset.y >= 0) 
        //it means table view is being scrolled up
        

希望对你有所帮助。

【讨论】:

我看到逻辑了,我需要坐标全局变量default,和scrolls坐标,方法应该比较当前坐标和之前的坐标与scrolls,如果向上滚动改变,确定去哪里如果返回向下坐标默认值,则某些约束为 0。有想法如何在这个方法中实现它?【参考方案3】:

这一行代码将解决所有top,bottom,left, right 约束到Zero 的问题

[self.tableView setContentInset:UIEdgeInsetsMake(520, 0, 0, 0)];

【讨论】:

我将此代码添加到 (void)scrollViewDidScroll:(UIScrollView *)scrollView 但它不起作用 添加到 -viewdidload() 中,无需实现 -scrollViewDidScroll:()【参考方案4】:

请试试这个,它会帮助你....

-(void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset

    if (scrollView.tag != 1)
    
        return;
    

    if(self.heightLogTabTableView.contentOffset.y<0)
    
        self.heightLogTabTableView.constant = 0;

            [UIView animateWithDuration:0.5f animations:^
                [self.view layoutIfNeeded];
            ];
    
    else 
    
        self.heightLogTabTableView.constant = 520;
            [UIView animateWithDuration:0.5f animations:^
                [self.view layoutIfNeeded];
            ];
        

【讨论】:

【参考方案5】:

我在我的 .h 文件 "@property (nonatomic) CGFloat lastScrollOffset;" 中添加全局变量 CGFloat

    - (void)scrollViewDidScroll:(UIScrollView *)scrollView

    if (scrollView.tag == 1)


        if (scrollView.contentOffset.y > _lastScrollOffset) 

            self.heightLogTabTableView.constant = 0;

            [UIView animateWithDuration:0.5f animations:^
                [self.view layoutIfNeeded];
            ];
         else if (scrollView.contentOffset.y < _lastScrollOffset) 

            self.heightLogTabTableView.constant = self.informationTask.frame.size.height;

            [UIView animateWithDuration:0.5f animations:^
                [self.view layoutIfNeeded];
            ];
        

        _lastScrollOffset = scrollView.contentOffset.y;
    

    else if (scrollView.tag == 2)

     if (scrollView.contentOffset.y > _lastScrollOffset) 

         self.heightCommentTabTableView.constant = 0;
         [UIView animateWithDuration:0.5f animations:^
             [self.view layoutIfNeeded];

             self.typeCommentView.hidden = NO;

         ];

      else if (scrollView.contentOffset.y < _lastScrollOffset) 

         self.heightCommentTabTableView.constant = self.informationTask.frame.size.height + 220;

         [UIView animateWithDuration:0.5f animations:^
             [self.view layoutIfNeeded];
             self.typeCommentView.hidden = YES;
         ];
        
    

【讨论】:

我需要在 scroll.contentOffset.y 中比较我的全局变量。

以上是关于滚动 UITableView 时如何创建 NSLayoutConstraint的主要内容,如果未能解决你的问题,请参考以下文章

如何让 uitableview 知道在哪里滚动未创建的视图

UITableView - 如何在用户滚动时保持表格行固定

为啥我的 UITableView 单元格在滚动时重叠?

滚动时如何使 UITableView 从下到上显示?

滚动时如何使uitableview单元格不改变?

如何在滚动时更新 UITableView 数据