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
,你应该在UITapBar
s的情况下使用它。
这是一些示例代码(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,请不要使用它)
文档说topLayoutGuide
和bottomLayoutGuide
包括导航栏和标签栏。所以也许你在加载视图之前检索长度?
嗯,我的视图层次结构是 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.frame
或viewController.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