为什么在iOS7的UITableViewStyleGrouped风格的UITableView的顶部有额外的填充
从iOS7开始,在我的UITableView
的顶部有一个额外的空间,它有一个样式UITableViewStyleGrouped
。
这里是一个例子:
tableview从第一个箭头开始,有35个像素的不明原因的填充,然后绿色的头是由viewForHeaderInSection
(其中部分为0)返回的UIView
。
任何人都可以解释这35像素的数量来自哪里,我怎么能摆脱它,而不切换到UITableViewStylePlain
?
我得到以下帮助:
YouStoryboard.storyboard> YouViewController>属性检查器>取消选中 – 调整滚动视图插图。
我玩了更多,似乎这是设置tableView的tableHeaderView = nil
的副作用。
因为我的tableView有一个dynamic的出现tableHeaderView
,当我需要隐藏tableHeaderView
,而不是做self.tableView.tableHeaderView = nil;
, 我做:
self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.tableView.bounds.size.width, 0.01f)];
我喜欢这个解决scheme比设置一个有点任意的contentInset.top
因为我contentInset.top
dynamic地使用contentInset.top
。 不得不记住,每当我重新计算contentInset.top
时,删除额外的35px是乏味的。
对于IOS 7,如果你正在视图控制器中分配一个tableview,你可以看看
self.edgesForExtendedLayout = UIRectEdgeNone;
你的问题和我的似乎很相似
更新:
Swift的iOS 9.x:
self.edgesForExtendedLayout = UIRectEdge.None
Swift 3:
self.edgesForExtendedLayout = UIRectEdge.init(rawValue: 0)
尝试更改UITableView
从UIScrollView
inheritance的contentInset
属性。
self.tableView.contentInset = UIEdgeInsetsMake(-36, 0, 0, 0);
这是一个解决方法,但它的工作原理
self.automaticallyAdjustsScrollViewInsets = NO;
尝试,你可以处理它!
您可以检测到您的应用程序是否运行iOS7或更高版本,并在您的表视图委托中添加这两个方法(通常在您的UIViewController代码中)
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { return CGFLOAT_MIN; } -(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { return CGFLOAT_MIN; }
这可能不是一个优雅的解决scheme,但为我工作
取消选中“调整滚动查看插图”
我find了我原来的错误的原因,并创build了一个示例项目展示它。 我相信有一个iOS7的错误。
从iOS7开始,如果使用分组样式创buildUITableView,但没有在第一个布局上设置委托,那么您设置委托并调用reloadData,顶部将会有一个永远不会消失的35像素的空间。
看到这个项目,我展示了这个bug: https : //github.com/esilverberg/TableViewDelayedDelegateBug
特别是这个文件: https : //github.com/esilverberg/TableViewDelayedDelegateBug/blob/master/TableViewDelayedDelegateBug/ViewController.m
如果第24行被激活,
[self performSelector:@selector(updateDelegate) withObject:nil afterDelay:0.0];
顶部会有一个额外的35像素的空间。 如果第27行被激活,24被注释掉,
self.tableView.delegate = self;
顶部没有空间。 这就像tableViewcaching结果的地方,而不是在委托设置和reloadData被调用后重绘自己。
另一个快速的评论…即使在XCode 6.1,有一个垂直空间出现在UIScrollViews
, UITextViews
和UITableViews
顶部的错误。
有时,解决这个问题的唯一方法是进入故事板并拖动问题控件,使其不再是页面上的第一个子视图。
(感谢Oded指出我在这个方向上……我发表了这个评论,只是为了添加一些截图,来演示症状和修复。)
根据Apple 针对iOS7的转换指南 ,滚动视图的内容插入会自动进行调整。 automaticallyAdjustsScrollViewInsets的默认值被设置为YES。
具有UITableView的UIViewController应将此属性设置为NO。
self.automaticallyAdjustsScrollViewInsets = NO;
这将做的伎俩。
编辑1:
另外,可以尝试 –
self.navigationController.navigationBar.translucent = YES;
这也删除了顶部的额外填充。
在使用分组的TableView时,使用这个来避免在viewWillAppear中边界切割
self.tableView.contentInset = UIEdgeInsetsMake(-35, 0, 0, 0);
故事板:
只需取消选中:在View Controller的选项中Adjust Scroll View Insets
码:
self.automaticallyAdjustsScrollViewInsets = false
上面的很多回答太hacky。 如果苹果决定解决这个意外的行为,他们将在未来的任何时候突破。
问题的根源:
-
一个
UITableView
不喜欢有一个高度为0.0的标题。 如果你想要做的是有一个高度为0的标题,你可以跳转到解决scheme。 -
即使稍后将一个非0.0高度分配给您的头文件,
UITableView
也不喜欢先分配一个高度为0.0的头文件。
解:
然后,最简单可靠的解决方法是确保您的标题高度不是0时,将其分配给您的表视图。
像这样的东西可以工作:
// Replace UIView with whatever class you're using as your header below: UIView *tableViewHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.tableView.bounds.size.width, CGFLOAT_MIN)]; self.tableView.tableHeaderView = tableViewHeaderView;
像这样的事情在某个时候会导致问题(通常在滚动之后):
// Replace UIView with whatever class you're using as your header below: UIView *tableViewHeaderView = [[UIView alloc] initWithFrame:CGRectZero]; self.tableView.tableHeaderView = tableViewHeaderView;
在我的情况下,这是对我的帮助。 我也支持ios6。
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) { self.edgesForExtendedLayout = UIRectEdgeNone; self.extendedLayoutIncludesOpaqueBars = NO; self.automaticallyAdjustsScrollViewInsets = NO; }
只需将以下内容添加到VC中的viewDidLoad:
self.automaticallyAdjustsScrollViewInsets = NO;
Swift:iOS我有滚动视图上的tableview ..当我点击“返回”在同一屏幕上。 滚动视图上占用更多的空间..解决这个我用过:
self.automaticallyAdjustsScrollViewInsets = false
一个布尔值,指示视图控制器是否应该自动调整其滚动视图插图。 默认值为true,允许视图控制器根据状态栏,导航栏和工具栏或选项卡栏使用的屏幕区域来调整其滚动视图插图。 如果您想自己pipe理滚动视图插入调整,例如当视图层次结构中有多个滚动视图时,则设置为false。
我的答案将是更一般的答案,但也可以应用于此。
如果( ViewController的 ) 根视图或根视图的第一个子视图(子视图)是UIScrollView(或UIScrollView本身)的子类,并且if
self.navigationController.navigationBar.translucent = YES;
框架会自动设置预先计算的contentInset 。
为了避免这个,你可以做
self.automaticallyAdjustsScrollViewInsets = NO;
但在我的情况下,我无法做到这一点,因为我正在实施SDK,其中有UIView组件,可供其他开发人员使用。 该UIView组件包含UIWebView(其中有UIScrollView作为第一个子视图)。 如果该组件被添加为UIViewController视图层次结构中的第一个子项,则系统将自动应用insets。
我已经通过在添加UIWebView之前添加虚框视图(0,0,0,0)来解决这个问题。
在这种情况下,系统没有findUIScrollView的子类作为第一个子视图,也没有应用插入
感谢@Aurelien Porte的回答。 这是我的解决scheme
这个问题的原因: –
- 一个UITableView不喜欢有一个高度为0.0的标题。 如果你想要做的是有一个高度为0的标题,你可以跳转到解决scheme。
- 即使稍后将一个非0.0高度分配给您的头文件,UITableView也不喜欢先分配一个高度为0.0的头文件。
在ViewDidLoad中: –
self.edgesForExtendedLayout = UIRectEdge.None self.automaticallyAdjustsScrollViewInsets = false
不需要像这样的东西: –
self.myTableview.contentInset = UIEdgeInsetsMake(-56, 0, 0, 0)
在heightForHeaderInSection
委托中: –
if section == 0 { return 1 } else { return 40; // your other headers height value }
在viewForHeaderInSection
委托中: –
if section == 0 { // Note CGFloat.min for swift // For Objective-c CGFLOAT_MIN let headerView = UIView.init(frame: CGRectMake(0.0, 0.0, self.myShaadiTableview.bounds.size.width, CGFloat.min)) return headerView } else { // Construct your other headers here }
所以我在这里尝试了所有的方法,而这次他们都没有帮助。 我的情况是在iOS 9上分组的表格视图。我不知道为什么,怎么find这个,但是对于我来说,设置一个至less有0.01
高度的UIView
的tableViewHeader
出来了。 CGRectZero
没有帮助,没有什么帮助:
tableView.tableHeaderView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 0.0, height: 0.01))
这是使用Swift 3的iOS 10的解决scheme:
您可以通过从UITableViewDelegate
实现以下方法来摆脱顶部和底部的填充。
func tableView( _ tableView: UITableView, heightForHeaderInSection section: Int ) -> CGFloat { return CGFloat.leastNormalMagnitude } func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { return CGFloat.leastNormalMagnitude }
我假设这只是新的UITableViewStyleGrouped
样式的一部分。 这是在所有分组表格的意见,似乎没有任何直接的方式来控制这个空间。
如果这个空间是由一个UIView
表示的,那么可以searchUITableView
所有subviews
来find这个特定的视图并直接编辑它。 然而,在标题和单元格开始之前,这个空间也可能只是一个硬编码的偏移量,并且没有任何方法可以编辑它。
要search所有的子视图(当表格没有单元格时,我会运行这个代码,以使它更容易读取输出):
- (void)listSubviewsOfView:(UIView *)view { // Get the subviews of the view NSArray *subviews = [view subviews]; // Return if there are no subviews if ([subviews count] == 0) return; for (UIView *subview in subviews) { NSLog(@"%@", subview); // List the subviews of subview [self listSubviewsOfView:subview]; } }
我有和arielyz一样的解决方法。 一旦我移动UITableView不是父视图的第一个子视图,它就消失了。 我的空间是20像素,而不是35。
我不能在一个肖像xib,只有一个景观xib重新创build它。 如果我可以在一个简单的演示应用程序中重现它,我会稍后提交一个雷达错误。
我认为使UIEdgeInsets -35 0 0 0是单调乏味的。 在我的情况下,我实现了tableView:heightForHeaderInSection:方法,它有可能返回0。
当我改变0到0.1f时,问题就消失了。
使用这一个我认为这有助于… … –
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { return 0.005f;// set this according to that you want... }
override func viewWillAppear(animated: Bool) { self.edgesForExtendedLayout = UIRectEdge.None // OR self.sampleTableView.contentInset = UIEdgeInsetsMake(-64, 0, 0, 0); //OR self.automaticallyAdjustsScrollViewInsets = false }
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ return CGFLOAT_MIN; }
这就是所有人!
我也一直在抨击这个问题。 很确定这是一个iOS7的错误。 最终帮助我的是xib中的观点顺序。 我有一个视图正确显示表视图,另一个表视图有额外的35px空间。 (UITableView明智)之间的唯一区别是,在不良显示视图UITableView是第一个孩子,而在正确显示的视图,这是第二个。
这对我来说只是改变视图的顺序。 我真的不希望为解决方法添加额外的代码行…
我们有多个答案。
1)你可以添加UIImageview视图didload
UIImageView * imbBackground = [UIImageView new]; [self.view addSubview:imbBackground];
2)您可以设置页眉和页脚高度0.1
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { return 0.1; } - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ return 0.1; }
3)您可以添加高度为0.1的页眉和页脚视图
tblCampaigns.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, tblCampaigns.bounds.size.width, 0.01f)]; tblCampaigns.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, tblCampaigns.bounds.size.width, 0.01f)];
只需在视图的绝对顶部固定你的tableview(或者开始)。 额外的不需要的空间恰好是导航栏的高度。
下面做的(Swift)解决了这个问题, 但是当你不需要头部的时候,这个工作就可以解决。
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { return CGFloat.min }
如果你这样做,你将不得不放弃第一部分,并使用其他的内容。
UITableViewDataSource
实现:
func numberOfSectionsInTableView(tableView: UITableView) -> Int { return <number_of_data_sections>+1 } func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // the first section we don't use for data if section == 0 { return 0 } // starting from 1, there are sections we use if section == 1 { let dataSection = section - 1 // use dataSection for your content (useful, when data provided by fetched result controller). For example: if let sectionInfo = myFRC!.sections![dataSection] as? NSFetchedResultsSectionInfo { return sectionInfo.numberOfObjects } } return 0 } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let dataIndexPath = NSIndexPath(forRow: indexPath.row, inSection: (indexPath.section - 1) ) // return cell using transformed dataIndexPath } func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { if section == 1 { // return your header height } return CGFloat.min } func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { if section == 1 { // return your header view } return nil } func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { // in my case, even when 1st section header was of zero heigh, I saw the space, an that was a footer. I did not need footer at all, so always gave zero height return CGFloat.min }
就是这样。 模型不知道变化的任何内容,因为我们在访问数据时转换段号。