类似于 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 在隐藏后重新出现?
如何仅在获取数据完成时(在 Swift 中)隐藏我的 UIRefreshControl?
将 UIRefreshControl 与 UISearchBar 搜索结果一起使用
获取 `UIRefreshControl` 到 `UITableViewController` 内容上方的北边,而不是在标题下?