似乎这里的其他答案正在为下拉到 UINavigationBar 下方的通知提供解决方案。如果您仍在寻找位于 UITableView 的滚动视图中的解决方案,那么我会在表视图中添加一个自定义表头(而不是节头)。
以下是完成此操作所需的粗略步骤:
1.在加载时创建初始标题视图
我通常使用拥有 UITableView 实例变量的 UIViewController 子类(而不是使用 UITableViewController),但您应该能够通过任一设置来完成此操作。在您的 tableview 设置代码中(可能在 viewDidLoad 中),您可以在其中设置诸如 backgroundColor、contentInset、separatorStyle 等内容,创建一个将成为您的标题的 UILabel。然后将此 UILabel 设置为您的 tableView 的 tableHeaderView。当然,如果你想让这个“通知部分”变得更复杂一些,请随意将其设置为带有嵌套 UILabel + 其他内容的 UIView。所以像:
UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.tableView.bounds.size.width, 44.0f)];
headerLabel.backgroundColor = [UIColor clearColor]; // Just in case you have some fancy background/color in your table view
headerLabel.textAlignment = UITextAlignmentCenter;
headerLabel.font = ....
headerLabel.textColor = ....
headerLabel.text = @"You are an awesome user!";
self.tableView.tableHeaderView = headerLabel;
2.设置你的tableview加载“正常”(即不显示标题)
同样,在 viewDidLoad 中,您需要正确设置 tableview 的 contentOffset 和 alwaysBounceVertical 以在加载时隐藏此标题视图。contentOffset 设置为标题的高度将在标题下方开始 tableview 的 y 坐标。alwaysBounceVertical 设置为 YES 将允许您的 tableview 正常运行,即使您的 tableview 的 contentsize 小于您的屏幕尺寸。所以像:
self.tableView.contentOffset = (CGPoint){0.0f, 44.0f};
self.tableView.alwaysBounceVertical = YES;
3.添加滑下滑走
好的,现在有几种方法可以做到这一点。在 viewDidAppear 上,您可以创建一个链式 UIView 动画,其中第一个动画将 tableview 向下滑动(即将 contentOffset 设置为 {0.0f, 0.0f})延迟一秒,第二个动画将 tableview 向上滑动(即设置contentOffset 到 {0.0f, 44.0f}) 延迟两秒。或者您可以使用 GCD 并将两个动画安排为异步 + 延迟块。无论哪种方式都很好(并且可能有两种或三种其他好的方法可以实现这一点),但只是为了传达这个想法......你可以像这样链接动画:
__weak MyCustomViewController *me = self;
[UIView
animateWithDuration:0.4f
delay:1.0f
options:UIViewAnimationOptionAllowUserInteraction
animations:^
{
me.tableView.contentOffset = (CGPoint){0.0f, 0.0f};
}
completion:^(BOOL finished)
{
if (me.tableView)
{
[UIView
animateWithDuration:0.4f
delay:2.0f
options:UIViewAnimationOptionAllowUserInteraction
animations:^
{
me.tableView.contentOffset = (CGPoint){0.0f, 44.0f};
}
completion:^(BOOL finished)
{
if (me.tableView)
{
me.tableView.tableHeaderView = nil; // If you want to completely get rid of this notification header
me.tableView.contentOffset = (CGPoint){0.0f, 0.0f}; // I'm unsure if this will cause the tableview to jump... if it does, you can animate the headerview away instead of animating the tableview up to hide the header, then setting header to nil and reseting the contentOffset
// or
me.tableView.tableHeaderView.hidden = YES; // If you want to just hide the header
}
}];
}
}];
我编写了示例代码而没有对其进行任何测试......呵呵,所以它可能无法正常工作。但是,如果您需要更多帮助,我们很乐意帮助您充实这一点!祝你好运。
更新:允许用户滚动取消动画
我不太确定您希望桌子上的用户交互对动画做什么。如果您只想在用户开始滚动时取消动画,那么我会使用 GCD(参见下面的代码)。但我可以看到其他方法可以让动画与用户触摸一起工作,所以这取决于你在寻找什么。在任何情况下,假设任何用户触摸都应该禁用下一个预定的动画,那么可以使用以下两个函数来实现:
- (void)scheduleShowHeaderAnimation
{
__weak MyCustomViewController *me = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.0f * NSEC_PER_SEC), dispatch_get_main_queue(), ^ // Start animating after 1 sec delay
{
if (me.tableView) // Make sure the tableview is still around
{
if (! me.tableView.tracking && // Don't show animation if user has begun to touch contentview
! me.tableView.dragging && // Don't show animation if user has begun to drag contentview
! me.tableView.decelerating) // Don't show animation if dragging happened and scrollview is starting to decelerate
{
[UIView
animateWithDuration:0.4f
delay:0.0f
options:UIViewAnimationOptionAllowAnimatedContent // This will make sure user can interact with tableview while animation is going on
animations:^
{
me.tableView.contentOffset = (CGPoint){0.0f, 0.0f};
}
completion:^(BOOL finished)
{
[me scheduleHideHeaderAnimation];
}];
}
}
});
}
- (void)scheduleHideHeaderAnimation
{
__weak MyCustomViewController *me = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2.0f * NSEC_PER_SEC), dispatch_get_main_queue(), ^ // Start animating after 2 secs delay
{
if (me.tableView) // Make sure the tableview is still around
{
if (! me.tableView.tracking && // Don't show animation if user has begun to touch contentview
! me.tableView.dragging && // Don't show animation if user has begun to drag contentview
! me.tableView.decelerating) // Don't show animation if dragging happened and scrollview is starting to decelerate
{
[UIView
animateWithDuration:0.4f
delay:0.0f
options:UIViewAnimationOptionAllowAnimatedContent // This will make sure user can interact with tableview while animation is going on
animations:^
{
me.tableView.contentOffset = (CGPoint){0.0f, 44.0f};
}
completion:^(BOOL finished)
{
if (me.tableView)
{
me.tableView.tableHeaderView = nil; // If you want to completely get rid of this notification header
me.tableView.contentOffset = (CGPoint){0.0f, 0.0f}; // I'm unsure if this will cause the tableview to jump... if it does, you can animate the headerview away instead of animating the tableview up to hide the header, then setting header to nil and reseting the contentOffset
// or
me.tableView.tableHeaderView.hidden = YES; // If you want to just hide the header
}
}];
}
}
});
}
我会在 viewDidAppear 中调用 scheduleShowHeaderAnimation。
然后,当用户已经向下滚动 tableview 时,为了支持隐藏标题,我将实现UIScrollViewDelegate中的一个- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
或添加类似的内容:- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
if (self.tableView.tableHeaderView != nil)
{
self.tableView.tableHeaderView = nil;
}
// or
if (self.tableView.tableHeaderView.hidden == NO)
{
self.tableView.tableHeaderView.hidden = YES;
}
如果您想要支持更复杂的交互,或者如果您希望动画以不同的方式响应用户触摸,您可能需要覆盖其他 UIScrollViewDelegate 方法以及当用户开始与滚动视图交互时(这是父类表视图),然后更改动画的行为。
这会让你更接近你正在寻找的东西吗?