csdnceshi76
斗士狗
采纳率0%
2013-09-18 19:07 阅读 577
已采纳

为什么在 iOS7中 UITableView 风格组合的顶部会有额外的填充

Starting in iOS7, there is additional space at the top of my UITableView's which have a style UITableViewStyleGrouped.

Here is an example:

enter image description here

The tableview starts at the first arrow, there is 35 pixels of unexplained padding, then the green header is a UIView returned by viewForHeaderInSection (where the section is 0).

Can anyone explain where this 35 pixel amount is coming from and how I can get rid of it without switching to UITableViewStylePlain?

转载于:https://stackoverflow.com/questions/18880341/why-is-there-extra-padding-at-the-top-of-my-uitableview-with-style-uitableviewst

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

29条回答 默认 最新

  • 已采纳
    weixin_41568134 MAO-EYE 2013-10-05 05:52

    I have found the cause of my original bug and created a sample project showcasing it. I believe there is an iOS7 bug.

    As of iOS7, if you create a UITableView with the Grouped style, but do not have a delegate set on first layout, then you set a delegate and call reloadData, there will be a 35px space at the top that will never go away.

    See this project I made showcasing the bug: https://github.com/esilverberg/TableViewDelayedDelegateBug

    Specifically this file: https://github.com/esilverberg/TableViewDelayedDelegateBug/blob/master/TableViewDelayedDelegateBug/ViewController.m

    If line 24 is active,

    [self performSelector:@selector(updateDelegate) withObject:nil afterDelay:0.0];
    

    there will be an extra 35 px space at the top. If line 27 is active and 24 is commented out,

    self.tableView.delegate = self;
    

    no space at the top. It's like the tableView is caching a result somewhere and not redrawing itself after the delegate is set and reloadData is called.

    点赞 7 评论 复制链接分享
  • weixin_41568184 叼花硬汉 2013-10-29 02:32
    self.automaticallyAdjustsScrollViewInsets = NO;
    

    try, you can deal with it!

    点赞 30 评论 复制链接分享
  • weixin_41568110 七度&光 2013-10-01 13:36

    I was helped by the following:

    YouStoryboard.storyboard > YouViewController > Attributes inspector > Uncheck - Adjust scroll view insets.

    enter image description here

    点赞 27 评论 复制链接分享
  • weixin_41568183 零零乙 2013-09-20 21:16

    For IOS 7 if you are allocing a tableview in a view controller you may look into

    self.edgesForExtendedLayout = UIRectEdgeNone;
    

    your problem seemed similar to mine

    Update:

    Swift in iOS 9.x:

    self.edgesForExtendedLayout = UIRectEdge.None
    

    Swift 3 :

    self.edgesForExtendedLayout = UIRectEdge.init(rawValue: 0)
    
    点赞 24 评论 复制链接分享
  • csdnceshi73 喵-见缝插针 2013-09-21 17:32

    Try changing the contentInset property that UITableView inherits from UIScrollView.

    self.tableView.contentInset = UIEdgeInsetsMake(-36, 0, 0, 0);
    

    It's a workaround, but it works

    点赞 22 评论 复制链接分享
  • csdnceshi73 喵-见缝插针 2013-09-21 23:33

    I played around with it a bit more and it seems like this is a side-effect of setting the tableView's tableHeaderView = nil.

    Because my tableView has a dynamically appearing tableHeaderView, when I need to hide the tableHeaderView, instead of doing self.tableView.tableHeaderView = nil;, I do:

    self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.tableView.bounds.size.width, 0.01f)];
    

    I like this solution better than setting a somewhat arbitrary contentInset.top because I use the contentInset.top dynamically as well. Having to remember to remove an extra 35px whenever I recalculate contentInset.top is tedious.

    点赞 21 评论 复制链接分享
  • csdnceshi52 妄徒之命 2013-10-27 10:31

    I've been banging my head against this one as well. Pretty sure this is an iOS7 bug. What helped me eventually, is the order of views in the xib. I had one view in which table view was displayed correctly, and another in which the table view had that extra 35px space. The only difference between then (UITableView wise), is that in the bad-displaying view UITableView was the first child, whereas in the view which was displaying correctly, it was the second.

    That did the trick for me, just changing the order of views. I really prefer not to add extra lines of code for a workaround...

    点赞 10 评论 复制链接分享
  • csdnceshi60 ℡Wang Yan 2013-09-25 09:10

    In my case this was what helped me. I'm supporting ios6 also.

    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
        self.edgesForExtendedLayout = UIRectEdgeNone;
        self.extendedLayoutIncludesOpaqueBars = NO;
        self.automaticallyAdjustsScrollViewInsets = NO;
    }
    
    点赞 9 评论 复制链接分享
  • weixin_41568131 10.24 2015-05-21 10:29

    Storyboard:

    Just uncheck: Adjust Scroll View Insets in View Controller's options

    enter image description here

    Code:

    self.automaticallyAdjustsScrollViewInsets = false
    
    点赞 9 评论 复制链接分享
  • weixin_41568126 乱世@小熊 2016-07-21 13:07

    So I was trying every method here, and this time none of them helped. My case was a grouped table view on iOS 9. I don't really know why and how I found out this one, but for me, setting the tableViewHeader with a UIView with at least 0.01 height worked out. CGRectZero didn't help, nothing really helped:

    tableView.tableHeaderView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 0.0, height: 0.01))
    
    点赞 9 评论 复制链接分享
  • csdnceshi72 谁还没个明天 2014-08-02 23:45

    I think making UIEdgeInsets -35 0 0 0 is tedious. In my case, I implemented tableView: heightForHeaderInSection: method and it has a potential to return 0.

    When I changed 0 to 0.1f, the problem just went away.

    点赞 8 评论 复制链接分享
  • csdnceshi55 ~Onlooker 2016-08-26 03:51

    Uncheck "Adjust Scroll View insets"

    enter image description here

    点赞 8 评论 复制链接分享
  • csdnceshi78 程序go 2013-10-25 18:26

    You could detect if your app is running iOS7 or greater and add this two methods in your table view delegate (usually in your UIViewController code)

    -(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
        return CGFLOAT_MIN;
    }
    
    -(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
        return CGFLOAT_MIN;
    }
    

    This maybe is not an elegant solution but works for me

    点赞 7 评论 复制链接分享
  • csdnceshi62 csdnceshi62 2014-01-15 12:32

    According to this transition guide for iOS7 by Apple, the scroll view’s content insets is automatically adjusted. The default value of automaticallyAdjustsScrollViewInsets is set to YES.

    The UIViewController which has the UITableView should set this property to NO.

    self.automaticallyAdjustsScrollViewInsets = NO;
    

    This will do the trick.

    EDIT 1:

    Also, one could try -

    self.navigationController.navigationBar.translucent = YES;
    

    This also removes the extra padding on the top.

    点赞 6 评论 复制链接分享
  • csdnceshi56 lrony* 2014-04-11 07:20

    I had the same fix as arielyz. Once I moved the UITableView to be not the first subview of the parent view, it went away. My space was 20 px, not 35.

    I wasn't able to recreate it in a portrait xib, only a landscape xib. I'll file a radar bug later if I can reproduce it in a simple demo app.

    点赞 6 评论 复制链接分享
  • csdnceshi72 谁还没个明天 2015-10-26 11:57

    use this one i think this help...

     - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
     {
        return 0.005f;// set this according to that you want...
     }
    
    点赞 6 评论 复制链接分享
  • csdnceshi61 derek5. 2016-05-30 09:42

    Thanks to the answer by @Aurelien Porte. Here is my solution

    Cause of this issue:-

    1. a UITableView doesn't like to have a header with a height of 0.0. If what's you're trying to do is to have a header with a height of 0, you can jump to the solution.
    2. even if later you assign a non 0.0 height to your header, a UITableView doesn't like to be assigned a header with a height of 0.0 at first.

    In ViewDidLoad:-

    self.edgesForExtendedLayout = UIRectEdge.None
    
    self.automaticallyAdjustsScrollViewInsets = false
    

    No Need For Something Like This :-

    self.myTableview.contentInset = UIEdgeInsetsMake(-56, 0, 0, 0)
    

    In heightForHeaderInSection delegate:-

    if section == 0
        {
            return 1
        }
        else
        {
            return 40; // your other headers height value
        }
    

    In viewForHeaderInSection delegate :-

    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 
    }
    
    点赞 6 评论 复制链接分享
  • csdnceshi63 elliott.david 2013-09-18 20:12

    I'm assuming that is just part of the new UITableViewStyleGrouped styling. It is in all grouped table views and there doesn't seem to be any direct way to control that space.

    If that space is being represented by a UIView, it would be possible to search through all the subviews of the UITableView to find that specific view and edit it directly. However, there is also the possibility that that space is just a hardcoded offset before headers and cells start and there won't be any way to edit it.

    To search through all subviews (I would run this code when the table has no cells, to make it a little easier to read the output):

    - (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];
        }
    }
    
    点赞 5 评论 复制链接分享
  • weixin_41568196 撒拉嘿哟木头 2015-07-04 17:33

    A lot of the previous answers above are too hacky. They would break at anytime in the future if Apple decides to fix this unexpected behavior.

    Root of the issue:

    1. a UITableView doesn't like to have a header with a height of 0.0. If what's you're trying to do is to have a header with a height of 0, you can jump to the solution.

    2. even if later you assign a non 0.0 height to your header, a UITableView doesn't like to be assigned a header with a height of 0.0 at first.

    Solution:

    Then, the most simple and reliable fix is to ensure that your header height is not 0 when you assign it to your table view.

    Something like this would work:

    // 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;
    

    Something like this would lead to the issue at some point (typically, after a scroll):

    // Replace UIView with whatever class you're using as your header below:
    UIView *tableViewHeaderView = [[UIView alloc] initWithFrame:CGRectZero];
    self.tableView.tableHeaderView = tableViewHeaderView;
    
    点赞 5 评论 复制链接分享
  • weixin_41568208 北城已荒凉 2017-01-12 16:37

    This is the solution for iOS 10 using Swift 3:

    You can get rid of top and bottom paddings by implementing the following methods from the UITableViewDelegate.

    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
    { 
        return CGFloat.leastNormalMagnitude
    }
    
    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat
    {
       return CGFloat.leastNormalMagnitude
    }
    
    点赞 5 评论 复制链接分享
  • weixin_41568110 七度&光 2014-04-29 10:43

    While using grouped TableView use this to avoid border cutting in viewWillAppear

    self.tableView.contentInset = UIEdgeInsetsMake(-35, 0, 0, 0);
    
    点赞 3 评论 复制链接分享
  • csdnceshi76 斗士狗 2015-01-07 08:14

    Another quick comment... even in XCode 6.1, there is a bug with vertical spaces appearing at the top of UIScrollViews, UITextViews and UITableViews.

    enter image description here

    Sometimes, the only way to fix this issue is to go into the Storyboard and drag the problem control so it's no longer the first subview on the page.

    enter image description here

    (My thanks to Oded for pointing me in this direction... I'm posting this comment, just to add a few screenshots, to demonstrate the symptoms and fix.)

    点赞 3 评论 复制链接分享
  • weixin_41568184 叼花硬汉 2015-12-02 14:20

    My answer is going to be more general answer, but can be applied on this as well.

    If the root view (of the ViewController) or the first child (subview) of the root view is subclass of the UIScrollView (or UIScrollView itself), and if

    self.navigationController.navigationBar.translucent = YES;
    

    framework will automatically set pre-calculated contentInset.


    To avoid this you can do

    self.automaticallyAdjustsScrollViewInsets = NO;
    

    but in my case I wasn't able to do this, because I was implementing SDK which has UIView component which can be used by other developers. That UIView component contains UIWebView (which has UIScrollView as the first subview). If that component is added as the first child in the UIViewController's view hierarchy, automatic insets will be applied by system.

    I've fixed this by adding dummy view with frame (0,0,0,0) before adding UIWebView.

    In this case system didn't find subclass of the UIScrollView as the first subview and didn't apply insets

    点赞 3 评论 复制链接分享
  • csdnceshi70 笑故挽风 2016-05-09 16:45
    -(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
    
        return CGFLOAT_MIN;
    }
    

    That's all folks!

    点赞 3 评论 复制链接分享
  • csdnceshi58 Didn"t forge 2014-09-20 05:20

    Simply add the following to your viewDidLoad in your VC:

    self.automaticallyAdjustsScrollViewInsets = NO;
    
    点赞 2 评论 复制链接分享
  • csdnceshi69 YaoRaoLov 2014-11-25 07:20

    Swift: iOS I had tableview on scroll view .. when I was click "Back" on the same screen. Scroll view take more space on top.. to solve this I have used :

     self.automaticallyAdjustsScrollViewInsets = false
    

    A Boolean value that indicates whether the view controller should automatically adjust its scroll view insets. Default value is true, which allows the view controller to adjust its scroll view insets in response to the screen areas consumed by the status bar, navigation bar, and toolbar or tab bar. Set to false if you want to manage scroll view inset adjustments yourself, such as when there is more than one scroll view in the view hierarchy.

    点赞 1 评论 复制链接分享
  • csdnceshi59 ℙℕℤℝ 2016-04-15 08:18
    override func viewWillAppear(animated: Bool) {
            self.edgesForExtendedLayout = UIRectEdge.None
    
     //  OR
    
    self.sampleTableView.contentInset = UIEdgeInsetsMake(-64, 0, 0, 0);
    
       //OR
    
     self.automaticallyAdjustsScrollViewInsets = false
            }
    
    点赞 1 评论 复制链接分享
  • weixin_41568126 乱世@小熊 2017-11-02 08:30

    This is how it can be fixed easily in iOS 11 and Xcode 9.1 through Storyboard:

    Select Table View > Size Inspector > Content Insets: Never

    点赞 1 评论 复制链接分享
  • csdnceshi73 喵-见缝插针 2018-04-14 12:08

    To be specific, to remove tableviewHeader space from top i made these changes:

    YouStoryboard.storyboard > YouViewController > Select TableView > Size inspector > Content insets - Set it to never.

    enter image description here

    点赞 1 评论 复制链接分享

相关推荐