iOS 7中的TableView在ViewController中和NavigationBar模糊效果

10
我开始在我的应用程序中使用Storyboard中的TableViewController构建一个TableView。当您这样做时,当您向下滚动列表时,背景的单元格会模糊显示,这是一种非常酷的效果。
后来,我不得不从TableViewController转移到包含TableView的ViewController(我需要在表的底部添加其他视图)。
为了避免第一个单元格被导航栏隐藏(在其上方),我添加了Top和Bottom Layout Guides以及视图的左右边缘的约束。
这很有效,但我失去了酷炫的模糊滚动效果:单元格似乎在进入导航栏之前就消失了。
我看到有人绕过这个问题,他们没有使用约束,在界面构建器中放置神奇数字。我不能这样做,首先因为我不喜欢它,其次因为我必须与iOS6兼容。
我错过了什么,以便再次受益于带有模糊导航栏效果?

你还遇到这个问题吗?作为将我的应用程序转换为ios7的一部分,我做了与你完全相同的操作(用uiviewcontroller替换uitableviewcontroller,并添加uitableview)。 uitableview与视图顶部对齐,原型内容在界面构建器中会自动被导航栏向下推。运行应用程序,内容从导航栏下方开始,滚动时在其下面滚动,透明度通过显示... - Marius Waldal
5个回答

11
您需要手动调整表格视图的contentInset并确保表格视图框架原点为0,0。 这样,表格视图将位于导航栏下方,但内容和滚动视图边缘之间会有一些边距(内容向下移动)。
建议您使用视图控制器的topLayoutGuide属性设置正确的contentInsets,而不是硬编码64(状态栏+导航栏)。 还有bottomLayoutGuide,在使用UITapBar时应该使用它。
以下是一些示例代码(viewDidLoad应该可以):
// Set edge insets
CGFloat topLayoutGuide = self.topLayoutGuide.length;
tableView.contentInset = UIEdgeInsetsMake(topLayoutGuide, 0, 0, 0);

顺便提一下,UIViewController的这些属性可能对您有所帮助(您不需要更改它们的默认值,但我不知道您的视图层次结构是什么):

  • automaticallyAdjustsScrollViewInsets 自动调整滚动视图插图
  • edgesForExtendedLayout 扩展布局边缘
  • extendedLayoutIncludesOpaqueBars 扩展布局是否包含不透明的栏

这差不多是对的。topLayoutGuide.length 不包括导航栏的高度。所以我做了像这样的事情: CGFloat topLayoutGuide = self.topLayoutGuide.length + self.tabBarController.navigationController.navigationBar.frame.size.height; (如果没有,请勿使用tabBarController) - Enrico Susatyo
文档说明 topLayoutGuidebottomLayoutGuide 包括导航栏和标签栏。也许您正在加载视图之前检索长度? - Alessandro Vendruscolo
嗯,我的视图层次结构是导航控制器->标签栏控制器->表视图控制器。也许topLayoutGuide没有意识到表视图在导航控制器中? - Enrico Susatyo
我会在 viewWillAppear 中尝试检查顶部布局指南的长度;此时它应该有一个值。另外,如果您正在使用自动布局,可以使用 VFL(如 https://dev59.com/PWIk5IYBdhLWcg3wi-tM 所示)设置指南的约束条件,只是我无法在官方文档中找到这个例子。 - Alessandro Vendruscolo

2

tableView需要全屏显示,即在顶部和底部栏下面。请注意不要使用顶部和底部布局指南,因为它们用于相对于栏的定位而不是在其下方。

然后,您需要手动设置tableview的内容插入。这将把初始滚动位置设置为顶部栏下方。

类似于这样:

CGSize statusBarSize = [[UIApplication sharedApplication] statusBarFrame].size;
CGFloat h=MIN(statusBarSize.width, statusBarSize.height);
UIEdgeInsets e = UIEdgeInsetsMake(self.navigationController.navigationBar.bounds.size.height + h,
                                             0.0f,
                                             0.0f,
                                             0.0f);

self.tableView.contentInset = e;

当使用tableView控制器和“自动调整内容插入”设置时,您可以免费获得此功能。

1

UIViewController 属性 edgesForExtendedLayout 可以解决问题。如果您正在使用故事板,请确保 Extended Edges Under Top Bars 是打开的(默认情况下已经打开)。 如果您是通过编程方式创建视图控制器,请尝试以下方法:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.edgesForExtendedLayout = UIRectEdgeAll;
}

当然,您的表视图需要具有正确的自动调整大小掩码/布局约束。

它能解决问题,但当单元格的最后一个底部像素到达导航栏底部时,它们突然消失了,就好像它们因为不在视图上而被释放了一样。有什么想法吗?否则我会将您的答案标记为已接受。 - ldavin
哦,我明白了,那么你应该尝试不同的方法:将表视图的起点设置为恰好在状态栏下方,并为表视图设置相应的contentInset。你明白我的意思吗?还是需要我提供一些代码? - dariaa
但是这样,在iOS 6上,导航栏和第一个部分标题之间不会有空白吗? - ldavin
是的,你需要将它包装在 if 语句中,并且只在 iOS 7 上执行。 - dariaa

1
你可能没有将 tableView 的坐标设置为 (0, 0),以映射到 viewController.view.frameviewController.view.bounds 的坐标系。如果你已经设置了,请尝试设置 self.navigationController.navigationBar.translucent = YES;

我不明白将坐标设置为任何值如何有助于我使用自动布局的约束条件? - ldavin

0

edgesForExtendedLayout不是你想要的,因为它会限制导航栏下面的表视图。在iOS 7中,视图控制器默认使用全屏,控制表视图内容开始位置的属性是automaticallyAdjustsScrollViewInsets。这应该默认为YES,因此请检查是否某种方式将其设置为NO,或尝试显式设置它。

查看此答案以了解如何工作的良好解释: https://dev59.com/q2Mk5IYBdhLWcg3w-Slm#19585104


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接