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

Posted

技术标签:

【中文标题】iOS 7 TableView 中的 ViewController 和 NavigationBar 模糊效果【英文标题】:iOS 7 TableView in a ViewController and NavigationBar blurred effect 【发布时间】:2013-10-10 15:05:25 【问题描述】:

我开始在故事板中使用 TableViewController 在我的应用程序中构建 TableView。执行此操作时,向下滚动列表时会产生非常酷的效果:在导航栏后面移动的单元格变得模糊。

一段时间后,我不得不从这个 TableViewController 移动到一个 ViewController 里面有一个 TableView(我必须在表格底部添加其他视图)。

为了避免第一个单元格被导航栏隐藏(在其上方),我在顶部和底部布局指南以及视图的左右边缘添加了约束。

这很好用,但我失去了酷炫的模糊滚动效果:单元格似乎在进入导航栏之前就消失了。

我已经看到人们不使用约束并将幻数放入界面生成器中的变通方法。我不能这样做,一是因为我不喜欢它,二是因为我必须兼容 ios 6。

我错过了什么才能再次从模糊的导航栏效果中受益?

【问题讨论】:

你还有这个问题吗?作为将我的应用程序转换为 ios7 的一部分(用 uiviewcontroller 替换 uitableviewcontroller),我做了与您完全相同的事情,向其中添加了 uitableview。 uitableview 一直对齐到视图的顶部,原型内容由界面生成器中的导航栏自动下推。运行应用,内容从导航栏下方开始,滚动时在其下方向上滚动,通过半透明显示... 【参考方案1】:

您必须手动调整表格视图的contentInset,并确保表格视图框架原点为0、0。 这样,表格视图将位于导航栏下方,但内容和滚动视图边缘之间会有一些边距(内容会向下移动)。

我建议你使用视图控制器的topLayoutGuide属性设置正确的contentInsets,而不是硬编码64(状态栏+导航栏)。 还有bottomLayoutGuide,你应该在UITapBars的情况下使用它。

这是一些示例代码(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,请不要使用它) 文档说topLayoutGuidebottomLayoutGuide 包括导航栏和标签栏。所以也许你在加载视图之前检索长度? 嗯,我的视图层次结构是 Navigation Controller -> TabBar Controller -> Table View Controller。也许 topLayoutGuide 没有意识到 table view 是在导航控制器中? 我会尝试检查viewWillAppear 中顶部布局指南的长度;那时它应该有一个值。另外,如果你使用 Auto Layout,你可以使用 VFL 为指南设置约束(如你所见***.com/questions/19174451/…,我只是在官方文档中找不到示例)【参考方案2】:

tableView 需要全屏。那是在顶部和底部栏的下方。注意不要使用顶部和底部布局指南,因为它们用于相对于不在下方的栏进行定位。

然后需要手动设置tableview的content inset。这会将初始滚动位置设置在顶栏下方。

类似:

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 控制器和“自动调整内容插入”设置时,您不能免费获得此功能

【讨论】:

【参考方案3】:

您的tableView 的坐标可能未设置为(0, 0) 以映射到viewController.view.frameviewController.view.bounds 的坐标。如果你已经这样做了,请尝试设置

self.navigationController.navigationBar.translucent = YES;

【讨论】:

我不明白将坐标设置为任何东西会有什么帮助,因为我使用了自动布局的约束?【参考方案4】:

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

- (void)viewDidLoad

    [super viewDidLoad];

    self.edgesForExtendedLayout = UIRectEdgeAll;

当然,您的表格视图需要有适当的自动调整掩码/布局约束

【讨论】:

它成功了,但是当单元格的最后一个底部像素到达导航栏的底部时,它们突然消失了,就好像它们被释放了,因为不再在视图上。任何的想法 ?否则,我会将您的答案标记为已接受 哦,我明白了,那么您应该尝试不同的方法:您应该将表格视图的原点设置在状态栏的正下方,并为您的表格视图设置相应的 contentInset。你明白我的意思还是我应该提供一些代码? 但是在 iOS 6 上我不会在导航栏和第一节标题之间有间隙吗? 是的,你会的,所以你必须将它包装在 if 语句中,并且只对 ios 7 执行此操作【参考方案5】:

edgesForExtendedLayout 不是您想要的,因为这会限制导航栏下方的表格视图。在 iOS 7 中,视图控制器默认使用全屏,控制 tableview 内容从哪里开始的属性是自动调整滚动视图插入。这应该默认为 YES,因此请检查它是否以某种方式设置为 NO,或者尝试显式设置。

查看此答案以获得有关其工作原理的良好解释: https://***.com/a/19585104/1485715

【讨论】:

以上是关于iOS 7 TableView 中的 ViewController 和 NavigationBar 模糊效果的主要内容,如果未能解决你的问题,请参考以下文章

iOS 7 中的 Spotlight TableView 是如何制作的?

只有在 iOS 7 中点击单元格时,tableview 单元格中的 labeltext 才会消失

Tableview 文本字段中的 iOS 在 for 循环中获取值在 ios 7 中不起作用,但在 iOS 8 中起作用

选择一个 TableView Cell 后,将数据传回 Swift 中的前一个 View Controller

tableView.contentInset 在 iOS 7 上损坏

iOS 7 TabBar 下 TableView 高度增加