类似于 UIRefreshControl 将隐藏的 UIView 添加到 UITableView

Posted

技术标签:

【中文标题】类似于 UIRefreshControl 将隐藏的 UIView 添加到 UITableView【英文标题】:Add hidden UIView to UITableView similar to UIRefreshControl 【发布时间】:2014-10-13 22:49:57 【问题描述】:

与 UIRefreshControl 非常相似,我试图将 UIView 放在 UITableView 之上。向下拖动 table view 应该会显示视图并将其保留在那里。向上拖动应该再次隐藏它,然后滚动表格视图。隐藏时,表格视图应正常滚动。滚动回顶部应该再次显示隐藏视图,或者捕捉到隐藏状态。最终显示的视图应该包含一些按钮或分段控件。它的外观和行为应该与 OmniFocus 应用程序非常相似。

OmniFocus 中的隐藏视图

OmniFocus 中的显示视图

这就是我得到的。尤其是当表格视图向上滚动时快速回到隐藏状态不起作用。如果时间安排得当,您最终会卡在顶视图的中间,这完全不是我想要的。

static CGFloat const kTopViewHeight = 40;

@interface ViewController ()
@property (nonatomic, weak) UIView *topView;
@property (nonatomic, assign) CGFloat dragStartY;
@end

@implementation ViewController

#pragma mark - View Lifecycle

- (void)viewDidLoad

    CGRect topViewFrame = CGRectMake(0.0, -kTopViewHeight, 320, kTopViewHeight);

    UIView *myView = [[UIView alloc] initWithFrame:topViewFrame];
    myView.backgroundColor = [UIColor greenColor]; // DEBUG
    self.topView = myView;
    [self.tableView addSubview:myView];


#pragma mark - UIScrollViewDelegate

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView

    NSLog(@"scrollViewWillBeginDragging %@", NSStringFromCGPoint(scrollView.contentOffset));
    self.dragStartY = scrollView.contentOffset.y;


- (void)scrollViewDidScroll:(UIScrollView *)scrollView

    NSLog(@"scrollViewDidScroll %@", NSStringFromCGPoint(scrollView.contentOffset));
    if (scrollView.contentOffset.y > 0) 
        // reset the inset
        scrollView.contentInset = UIEdgeInsetsZero;
     else if (scrollView.contentOffset.y >= -kTopViewHeight) 
        // set the inset for the section headers
        scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
     else if (scrollView.contentOffset.y < -kTopViewHeight) 
        // don't scroll further when the topView's height is reached
        scrollView.contentInset = UIEdgeInsetsMake(-kTopViewHeight, 0, 0, 0);
        scrollView.contentOffset = CGPointMake(0, -kTopViewHeight);
    


- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate

    NSLog(@"scrollViewDidEndDragging %@", NSStringFromCGPoint(scrollView.contentOffset));
    CGFloat yOffset = scrollView.contentOffset.y;

    if (yOffset < 0) 
        BOOL dragDown = self.dragStartY > yOffset;
        CGFloat dragThreshold = 10;

        if (dragDown) 
            if (yOffset <= -dragThreshold) 
                [self snapDown:YES scrollView:scrollView];
             else 
                [self snapDown:NO scrollView:scrollView];
            
         else if (!dragDown) 
            if (yOffset >= dragThreshold - kTopViewHeight) 
                [self snapDown:NO scrollView:scrollView];
             else 
                [self snapDown:YES scrollView:scrollView];
            
        
    


- (void)snapDown:(BOOL)down scrollView:(UIScrollView *)scrollView

    [UIView animateWithDuration:0.3
                          delay:0
                        options:UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionCurveEaseOut|UIViewAnimationOptionBeginFromCurrentState
                     animations:^
                         if (down) 
                             // snap down
                             scrollView.contentOffset = CGPointMake(0, -kTopViewHeight);
                             scrollView.contentInset = UIEdgeInsetsMake(kTopViewHeight, 0, 0, 0);
                          else 
                             // snap up
                             scrollView.contentOffset = CGPointMake(0, 0);
                             scrollView.contentInset = UIEdgeInsetsZero;
                         
                     
                     completion:nil];

【问题讨论】:

【参考方案1】:
//paging for data you can use this spinner

    spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
        [spinner stopAnimating];
        spinner.hidesWhenStopped = NO;
        spinner.frame = CGRectMake(0, 0, 320, 44);
        tblView.tableFooterView = spinner;
        tblView.tableFooterView.hidden = YES;

#pragma mark Table pull to refresh data....

    - (void)scrollViewDidEndDragging:(UIScrollView *)aScrollView
                      willDecelerate:(BOOL)decelerate

        CGPoint offset = aScrollView.contentOffset;
        CGRect bounds = aScrollView.bounds;
        CGSize size = aScrollView.contentSize;
        UIEdgeInsets inset = aScrollView.contentInset;
        float y = offset.y + bounds.size.height - inset.bottom;
        float h = size.height;

        float reload_distance = 50;
        if(y > h + reload_distance && _nextPage) 
            NSLog(@"load more data");
            tblView.tableFooterView.hidden = NO;
// index for new page of data will increment here
            index = index + 1;
            [spinner startAnimating];
            [self performSelector:@selector(requestData) withObject:nil afterDelay:1.0f];
        
    

   // when you request for data and wants to stop spinner 

     CGPoint offset = tblView.contentOffset;
    //    if new page is there set bool 
          _nextPage = YES;
    //    want to remove spinner
          tblView.tableFooterView.hidden = YES;
          [spinner stopAnimating];
          [tblView setContentOffset:offset animated:NO]; 

【讨论】:

也许我不清楚,但我不想替换 UIRefreshControl,也不需要任何刷新功能。它应该只是一个带有 UISegmentedControl 的静态视图,它看起来像一个 UIRefreshControl,它位于 UITableView 的顶部,并且在向下平移时会显示出来。

以上是关于类似于 UIRefreshControl 将隐藏的 UIView 添加到 UITableView的主要内容,如果未能解决你的问题,请参考以下文章

如何让 UIRefreshControl 在隐藏后重新出现?

使 UIRefreshControl 短于滑动

如何仅在获取数据完成时(在 Swift 中)隐藏我的 UIRefreshControl?

将 UIRefreshControl 与 UISearchBar 搜索结果一起使用

自定义 UIRefreshControl 动画

获取 `UIRefreshControl` 到 `UITableViewController` 内容上方的北边,而不是在标题下?