tableview状态栏 - ios隐藏状态栏




iOS 7:UITableView显示在状态栏下 (18)

我的应用程序的第一个屏幕是没有导航栏的UITableViewController ,这意味着内容在状态栏下面流动,所以有很多文本冲突。 我已经调整了下方Under top bars的属性和Adjust scroll view insets实际上停止滚动下的Adjust scroll view insets ,但代价是保留表视图的顶部。 我试图设置UITableView框架抵消20像素,但它似乎没有生效,因为我目前需要的应用程序与iOS 6兼容,我不能跳转到iOS 7故事板强制自动布局使用顶部高度指南。 有没有人找到适用于这两个版本的解决方案?

我尝试过的东西:设置edgesForExtendedLayout ,更改Storyboard中的设置,使其位于Under top bars edgesForExtendedLayout ,并Adjust scroll view ,将帧强制为新的区域。

一张图片胜过千言万语:


Abrahamchez的解决方案https://developer.apple.com/library/ios/qa/qa1797/_index.html为我工作如下。 我有一个单一的UITableview控制器作为我的初始视图。 我曾尝试偏移代码并嵌入到navcon中,但都没有解决状态栏透明度问题。

添加一个ViewController并使其成为初始视图。 这应该会显示关键的顶部和底部布局指南。

将旧的Tableview拖到新控制器的View中。

把所有的东西都改装成新的控制器:

将旧的视图controller.h文件更改为UIViewController而不是UITableViewController的继承/子类。

将UITableViewDataSource和UITableViewDelegate添加到视图控制器的.h。

重新连接故事板中所需的任何内容,例如搜索栏。

重要的是要设置好约束条件,就像Apple Q&A一样。 我没有打扰插入一个工具栏。 不确定确切的顺序。 但是布局指南中出现了一个红色图标,可能是我建立时的图标。 我点击它,让Xcode安装/清理约束。

然后,我点击各处,直到找到垂直空间约束,并将其顶部值从-20更改为0,并且完美运行。


Works for swift 3 - 在viewDidLoad();

let statusBarHeight = UIApplication.shared.statusBarFrame.height

let insets = UIEdgeInsets(top: statusBarHeight, left: 0, bottom: 0, right: 0)
tableView.contentInset = insets
tableView.scrollIndicatorInsets = insets

此代码:1.获取状态栏的高度2.给表格视图的顶部插入一个等于状态栏高度的内容。 3.为滚动指示器提供相同的插入,因此它出现在状态栏下方。


以下解决方案在代码中运行良好,无需使用魔术常量,并为用户更改大小类(例如通过ipad上的旋转或并排应用)进行说明:

- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
    [super traitCollectionDidChange:previousTraitCollection];
    // Fix up content offset to ensure the tableview isn't underlapping the status bar.
    self.tableView.contentInset = UIEdgeInsetsMake(self.topLayoutGuide.length, 0.0, 0.0, 0.0);
}

使用XIB时,chappjc的答案很有用。

以编程方式创建TableViewController时,我发现最简洁的解决方案是将UITableViewController实例包装在另一个UIViewController中并相应地设置约束。

这里是:

UIViewController *containerLeftViewController = [[UIViewController alloc] init];
UITableViewController *tableViewController = [[UITableViewController alloc] init];

containerLeftViewController.view.backgroundColor = [UIColor redColor];

hostsAndMoreTableViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
[containerLeftViewController.view addSubview:tableViewController.view];

[containerLeftViewController addChildViewController:tableViewController];
[tableViewController didMoveToParentViewController:containerLeftViewController];

NSDictionary * viewsDict = @{ @"tableView": tableViewController.view ,
                              @"topGuide": containerLeftViewController.topLayoutGuide,
                              @"bottomGuide": containerLeftViewController.bottomLayoutGuide,
                              };
[containerLeftViewController.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[tableView]|"
                                                                                         options:0
                                                                                         metrics:nil
                                                                                           views:viewsDict]];
[containerLeftViewController.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[topGuide][tableView][bottomGuide]"
                                                                                         options:0
                                                                                         metrics:nil
                                                                                           views:viewsDict]];

干杯,本


在故事板上选择UIViewController,取消选中“延伸顶部条下的边”选项。 为我工作。 :)


如果你正在编写程序并使用没有UINavigationControllerUITableViewController ,最好的办法是在viewDidLoad执行以下操作:

斯威夫特3

self.tableView.contentInset = UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 0)

早些时候Swift

self.tableView.contentInset = UIEdgeInsetsMake(20.0f, 0.0f, 0.0f, 0.0f);

UITableViewController仍然会滚动到状态栏的后面,但在滚动到顶部时不会在它之下。


对于Xcode 7,取消选中导航栏的“半透明”复选标记适用于我。


对于任何有兴趣复制此内容的人,只需按照以下步骤操作:

  1. 创建一个新的iOS项目
  2. 打开主故事板并删除默认/初始UIViewController
  3. 从对象库中拖出一个新的UITableViewController
  4. 将其设置为初始视图控制器
  5. 为表格提供一些测试数据

如果你按照上面的步骤,当你运行应用程序,你会看到没有任何东西,包括调整Xcode的复选框,以“在{顶部,底部,不透明}酒吧下延伸边缘”的作品来阻止第一行出现在状态栏下,你也不能通过编程来解决这个问题。

例如在上面的情况下,以下将不起作用:

// These do not work
self.edgesForExtendedLayout=UIRectEdgeNone;
self.extendedLayoutIncludesOpaqueBars=NO;
self.automaticallyAdjustsScrollViewInsets=NO;

这个问题可能非常令人沮丧,我相信这是Apple的一个漏洞,尤其是因为它从对象库中预先连接UITableViewController

我不同意所有试图通过使用任何形式的“幻数”来解决此问题的人,例如“使用20px的三角洲”。 这种紧密耦合的编程绝对不是苹果希望我们在这里做的。

我发现了两个解决这个问题的方法:

  • 保留UITableViewController的场景
    如果您希望将UITableViewController保留在故事板中,而无需手动将其放置到另一个视图中,则可以将UITableViewController嵌入到UINavigationController (编辑器>嵌入>导航控制器)中,并在检查器中取消选中“显示导航栏”。 这解决了这个问题,不需要额外的调整,它还保留了故事板中的UITableViewController场景。

  • 使用AutoLayout并将UITableView嵌入到另一个视图中 (我相信这就是Apple希望我们这样做的原因)
    创建一个空的UIViewController并将其拖入你的UITableView 。 然后,按住Ctrl从你的UITableView拖动到状态栏。 当鼠标到达状态栏的底部时,您会看到一个Autolayout气泡,其中显示“顶部布局指南”。 释放鼠标并选择“垂直间距”。 这将告诉布局系统将其置于状态栏的正下方。

我已经在一个空应用程序上测试了两种方法,并且他们都工作。 您可能需要做一些额外的调整才能使它们适用于您的项目。


我为Retina / Non-Retina显示器做了这个

BOOL isRetina = FALSE;

if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
    if ([[UIScreen mainScreen] scale] == 2.0) {
        isRetina = TRUE;
    } else {
        isRetina = FALSE;
    }
}

if (isRetina) {
    self.edgesForExtendedLayout=UIRectEdgeNone;
    self.extendedLayoutIncludesOpaqueBars=NO;
    self.automaticallyAdjustsScrollViewInsets=NO;
}

我在ios 11中遇到了这个问题,但是ios 8 - 10.3.3的布局是正确的。 对于我的情况,我为Superview.Top Margin设置了一个垂直空间约束,而不是Superview.Top,它适用于ios 8 - 11。


我正在使用导航控制器和tableviewcontroller的UISplitViewController。 在尝试了许多解决方案之后,这在主视图中适用于我:

float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if (systemVersion >= 7.0f) {

    // Move the view down 20 pixels
    CGRect bounds = self.view.bounds;
    bounds.origin.y -= 20.0;
    [self.navigationController.view setBounds:bounds];

    // Create a solid color background for the status bar
    CGRect statusFrame = CGRectMake(0.0, -20.0, bounds.size.width, 20);
    UIView* statusBar = [[UIView alloc] initWithFrame:statusFrame];
    statusBar.backgroundColor = [UIColor whiteColor];
    [statusBar setAlpha:1.0f];
    [statusBar setOpaque:YES];
    [self.navigationController.view addSubview:statusBar];
}

它类似于Hot Licks的解决方案,但将子视图应用于navigationController。


我结束了使用一个额外的视图与所需的背景,在TableView后添加并放置在状态栏下:

    self.CoverView = [[UIView alloc]init];

    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {

    self.CoverView.frame = CGRectMake(0,0,self.view.bounds.size.width,20);
    }

    self.CoverView.backgroundColor = [UIColor whiteColor];
    self.TableView = [[UITableView alloc]initWithFrame:CGRectMake(0,
    self.CoverView.bounds.size.height,XXX, YYY)];
    [self.view addSubview:self.TableView];
    [self.view addSubview:self.CoverView];

这不是很漂亮,但它是一个相当简单的解决方案,如果您需要使用无xib视图,以及IOS6和IOS7


我通过将大小设置为自由格式来实现它


添加到最上面的答案:

在第二种方法起初看起来不起作用后,我做了一些额外的修补,并找到了解决方案。

TLDR; 顶级答案的第二个解决方案几乎可行,但对于某些版本的xCode ctrl +拖动到“顶部布局指南”并选择垂直间距不做任何事情。 但是,首先调整表格视图的大小,然后选择“顶部空间到顶部布局指南”即可

  1. 将一个空白的ViewController拖到故事板上。

  2. 将UITableView 对象拖到视图中。 (不是UITableViewController)。 使用蓝色布局指南将其放置在中心位置。

  1. 将UITableViewCell拖到TableView中。 这将是您的原型重用单元,所以不要忘记在属性选项卡下设置它的重用标识符,否则您会遇到崩溃。

  1. 创建您的UIViewController的自定义子类,并添加<UITableViewDataSource, UITableViewDelegate>协议。 不要忘记在Identity Inspector中将故事板的ViewController设置为此类。

  2. 在您的实现文件中为您的TableView创建一个出口,并将其命名为“tableView”

  1. 右键单击TableView并将数据源和委托拖动到您的ViewController。

现在为不剪切到状态栏的部分。

  1. 抓住桌面视图的顶部边缘并将其向下移动到靠近顶部的其中一个虚线蓝色自动布局指南

  1. 现在,您可以控制从表格视图拖动到顶部,并选择顶部空间到顶部布局指南

  1. 它会给你一个关于TableView模糊布局的错误,就是添加缺少约束和完成。

现在,您可以像正常一样设置您的表格视图,并且不会剪辑状态栏!


这将解决它的UITableViewController(没有任何幻数)。 我无法解决的唯一问题是如果你正在打电话,在这种情况下,tableView的顶部被压低太多。 如果有人知道如何解决这个问题,请告诉我们。

class MyTableViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()    
        configureTableViewTop()
    }

    override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
        coordinator.animateAlongsideTransition({ (context) -> Void in
            }, completion: { (context) -> Void in
                self.configureTableViewTop()
        })
    }

    func configureTableViewTop() { 
        tableView.contentInset.top = UIApplication.sharedApplication().statusBarFrame.height
    }
}

这是一个Swift 2.3。 (Xcode 8.0)解决方案。 我创建了UITableView的一个子类。

class MYCustomTableView: UITableView
{   
    override func drawRect(rect: CGRect) {
        super.drawRect(rect)
        contentInset    = UIEdgeInsetsZero
    }
}

内容Inset应始终为零(默认情况下)。 我手动将它设置为零。 你也可以添加一个检查方法,使检查,如果它不是你想要它只是得到正确的矩形。 只有在绘制tableview时才会反映这种变化(这种情况经常不会发生)。

不要忘记更新IB中的TableView(在TableViewController中,或者在ViewController中只是TableView)。


- (void) viewDidLayoutSubviews {
    if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
        self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;
        if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
            self.edgesForExtendedLayout = UIRectEdgeNone;   // iOS 7 specific
        CGRect viewBounds = self.view.bounds;
        CGFloat topBarOffset = self.topLayoutGuide.length;
        viewBounds.origin.y = topBarOffset * -1;
        self.view.bounds = viewBounds;
        self.navigationController.navigationBar.translucent = NO;
    }
}

https://developer.apple.com/library/ios/documentation/userexperience/conceptual/TransitionGuide/SupportingEarlieriOS.html#//apple_ref/doc/uid/TP40013174-CH14-SW1


override func viewDidLoad() {
 // your code

 if let nc = self.navigationController {
   yourView.frame.origin.y = nc.navigationBar.frame.origin.y + nc.navigationBar.frame.height
  }
}




uistatusbar