iOS 7:UITableView 显示在状态栏下

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18900428/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:24:20  来源:igfitidea点击:

iOS 7: UITableView shows under status bar

iosios7uistatusbar

提问by Nicholas Smith

The first screen of my application is a UITableViewControllerwithout a navigation bar, which means that the content flows under the status bar so there's a lot of text collisions. I've adjusted both the properties for Under top barsand Adjust scroll view insetswhich do actually stop it from scrolling under, but at the cost of keeping the top of the table view under. I've attempted to set the UITableViewframe to offset by 20 pixels, but it doesn't appear to take effect and as I currently need the app to be compatible with iOS 6 I can't jump to iOS 7 Storyboards to force autolayout to use the top height guide. Has anyone found a solution that works for both versions?

我的应用程序的第一个屏幕是UITableViewController没有导航栏的,这意味着内容在状态栏下方流动,因此存在大量文本冲突。我已经调整了 和 的属性Under top barsAdjust scroll view insets它们实际上阻止了它向下滚动,但代价是保持表格视图的顶部。我试图将UITableView框架设置为偏移 20 像素,但它似乎没有生效,因为我目前需要该应用程序与 iOS 6 兼容,我无法跳转到 iOS 7 Storyboards 以强制使用自动布局顶部高度指南。有没有人找到适用于两个版本的解决方案?

Things I've tried: setting edgesForExtendedLayout, changing the settings within Storyboard for Under top barsand Adjust scroll view, forcing the frame to a new area.

我尝试过的事情:设置edgesForExtendedLayout,更改 Storyboard 中的设置Under top barsAdjust scroll view,强制框架到新区域。

A picture is worth a thousand words: Status bar flow under

一张图片胜过千言万语: 状态栏流下

回答by marinosb

For anyone interested in replicating this, simply follow these steps:

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

  1. Create a new iOS project
  2. Open the main storyboard and delete the default/initial UIViewController
  3. Drag out a new UITableViewControllerfrom the Object Library
  4. Set it as the initial view controller
  5. Feed the table some test data
  1. 创建一个新的 iOS 项目
  2. 打开主故事板并删除默认/初始 UIViewController
  3. UITableViewController从对象库中拖出一个新的
  4. 将其设置为初始视图控制器
  5. 向表提供一些测试数据

If you follow the above steps, when you run the app, you will see that nothing, including tweaking Xcode's checkboxes to "Extend Edges Under {Top, Bottom, Opaque} Bars" works to stop the first row from appearing under the status bar, nor can you address this programmatically.

如果您按照上述步骤操作,当您运行该应用程序时,您将看不到任何内容,包括将 Xcode 的复选框调整为“在 {Top, Bottom, Opaque} Bars 下扩展边缘”可以阻止第一行出现在状态栏下方,你也不能以编程方式解决这个问题。

E.g. In the above scenario, the following will have noeffect:

例如,在上述情况下,下面将有没有效果:

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

This issue can be very frustrating, and I believe it is a bug on Apple's end, especially because it shows up in their own pre-wired UITableViewControllerfrom the object library.

这个问题可能非常令人沮丧,我相信这是 Apple 端的一个错误,特别是因为它出现在他们自己UITableViewController从对象库中预先连接的地方。

I disagree with everyone who is trying to solve this by using any form of "Magic Numbers" e.g. "use a delta of 20px". This kind of tightly coupled programming is definitely not what Apple wants us to do here.

我不同意任何试图通过使用任何形式的“魔术数字”(例如“使用 20 像素的增量”)来解决此问题的人。这种紧耦合的编程绝对不是苹果想让我们在这里做的。

I have discovered two solutions to this problem:

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

  • Preserving the UITableViewController's scene:
    If you would like to keep the UITableViewControllerin the storyboard, without manually placing it into another view, you can embed the UITableViewControllerin a UINavigationController(Editor > Embed In > Navigation Controller) and uncheck "Shows Navigation Bar" in the inspector. This solves the issue with no extra tweaking needed, and it also preserves your UITableViewController's scene in the storyboard.

  • Using AutoLayout and embedding the UITableViewinto another view(I believe this is how Apple wants us to do this):
    Create an empty UIViewControllerand drag your UITableViewin it. Then, Ctrl-drag from your UITableViewtowards the status bar. As the mouse gets to the bottom of the status bar, you will see an Autolayout bubble that says "Top Layout Guide". Release the mouse and choose "Vertical Spacing". That will tell the layout system to place it right below the status bar.

  • 保留UITableViewController的场景
    如果你想保持UITableViewController在故事板,而无需手动将它变成另一种观点,你可以嵌入UITableViewControllerUINavigationController在检查(编辑>嵌入>导航控制器),并取消选中‘显示导航栏’ . 这解决了这个问题,不需要额外的调整,它还可以UITableViewController在故事板中保留你的场景。

  • 使用 AutoLayout 并将其嵌入UITableView到另一个视图中(我相信这就是 Apple 希望我们这样做的方式)
    创建一个空的UIViewController并将您的拖入UITableView其中。然后,按住 Ctrl 键从您的UITableView方向拖动到状态栏。当鼠标到达状态栏的底部时,您将看到一个 Autolayout 气泡,上面写着“Top Layout Guide”。松开鼠标并选择“垂直间距”。这将告诉布局系统将它放在状态栏的正下方。

I have tested both ways on an empty application and they both work. You may need to do some extra tweaking to make them work for your project.

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

回答by lipka

If you are doing things programatically and are using a UITableViewControllerwithout a UINavigationControlleryour best bet is to do the following in viewDidLoad:

如果您以编程方式做事并且使用UITableViewController没有 aUINavigationController最好的办法是在 中执行以下操作viewDidLoad

Swift 3

斯威夫特 3

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

Earlier Swift

更早的斯威夫特

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

The UITableViewControllerwill still scroll behind the status bar but won't be under it when scrolled to the top.

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

回答by Stunner

Please note:This worked for me for the following configuration:

请注意:对于以下配置,这对我有用:

  • No navigation bar at the top of the screen (table view meets status bar)
  • Table view is non-scrollable
  • 屏幕顶部没有导航栏(表格视图遇到状态栏)
  • 表格视图不可滚动

If the above two requirements aren't met your milage may vary.

如果不满足上述两个要求,您的里程可能会有所不同。

Original Post

原帖

I created my view programmatically and this ended up working for me:

我以编程方式创建了我的视图,这最终对我有用:

- (void) viewDidLayoutSubviews {
    // only works for iOS 7+
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
        CGRect viewBounds = self.view.bounds;
        CGFloat topBarOffset = self.topLayoutGuide.length;

        // snaps the view under the status bar (iOS 6 style)
        viewBounds.origin.y = topBarOffset * -1;

        // shrink the bounds of your view to compensate for the offset
        viewBounds.size.height = viewBounds.size.height + (topBarOffset * -1);
        self.view.bounds = viewBounds;
    }
}

Source(in topLayoutGuidesection at bottom of pg.39).

来源(在第39 页底部的 topLayoutGuide 部分)。

回答by ErikAGriffin

Adding to the top answer:

添加到顶部答案:

after the 2nd method did not initially seem to work I did some additional tinkering and have found the solution.

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

TLDR; the top answer's 2nd solution almost works, but for some versions of xCode ctrl+dragging to "Top Layout Guide" and selecting Vertical Spacing does nothing. However, by first adjusting the size of the Table View and then selecting "Top Space to Top Layout Guide" works

TLDR;最佳答案的第二个解决方案几乎有效,但对于某些版本的 xCode ctrl+dragging 到“Top Layout Guide”并选择 Vertical Spacing 没有任何作用。但是,通过首先调整 Table View 的大小,然后选择“Top Space to Top Layout Guide”是可行的



  1. Drag a blank ViewController onto the storyboard. View Controller

  2. Drag a UITableView objectinto the View. (Not UITableViewController). Position it in the very center using the blue layout guides.

  1. 将一个空白的 ViewController 拖到情节提要上。 视图控制器

  2. 将一个 UITableView对象拖到 View 中。(不是 UITableViewController)。使用蓝色布局指南将其放置在正中央。

Table ViewCenter Image

表格视图中心图片

  1. Drag a UITableViewCell into the TableView. This will be your prototype reuse cell, so don't forget to set it's Reuse Identifier under the Attributes tab or you'll get a crash.
  1. 将一个 UITableViewCell 拖入 TableView。这将是您的原型重用单元格,所以不要忘记在“属性”选项卡下设置它的“重用标识符”,否则您会崩溃。

Add Table View CellReuse Identifier

添加表格视图单元格重用标识符

  1. Create your custom subclass of UIViewController, and add the <UITableViewDataSource, UITableViewDelegate>protocols. Don't forget to set your storyboard's ViewController to this class in the Identity Inspector.

  2. Create an outlet for your TableView in your implementation file, and name it "tableView"

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

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

Create OutlettableView

创建出口表视图

  1. Right click the TableView and drag both the dataSource and the delegate to your ViewController.
  1. 右键单击 TableView 并将数据源和委托拖到您的 ViewController 中。

dataSource delegate

数据源委托

Now for the part of not clipping into the status bar.

现在是不剪辑到状态栏的部分。

  1. Grab the top edge of your Table View and move it down to one of the dashed blue auto-layout guides that are near the top
  1. 抓住表格视图的顶部边缘并将其向下移动到靠近顶部的蓝色虚线自动布局指南之一

resize

调整大小

  1. Now, you can control drag from the Table View to the top and select Top Space to Top Layout Guide
  1. 现在,您可以控制从 Table View 拖动到顶部并选择 Top Space to Top Layout Guide

Top Space to Top Layout Guide

顶部空间到顶部布局指南

  1. It will give you an error about ambiguous layout of TableView, just Add Missing Constraints and your done.
  1. 它会给你一个关于 TableView 不明确布局的错误,只需添加缺少的约束就可以了。

Add Missing Constraints

添加缺少的约束

Now you can set up your table view like normal, and it won't clip the status bar!

现在你可以像平常一样设置你的表格视图,它不会剪掉状态栏!

回答by Olzh

- (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

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

回答by pegpeg

Select UIViewController on your storyboard an uncheck option Extend Edges Under Top Bars. Worked for me. : )

在情节提要上选择 UIViewController 取消选中“在顶部栏下扩展边缘”选项。为我工作。:)

回答by uplearnedu.com

This is how to write it in "Swift" An adjustment to @lipka's answer:

这是如何在“Swift”中编写它对@lipka答案的调整:

tableView.contentInset = UIEdgeInsetsMake(20.0, 0.0, 0.0, 0.0)

回答by David T

For Xcode 7, un-ticking the 'translucent' check mark for the Navigation Bar worked for me.

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

enter image description here

在此处输入图片说明

回答by Harris

This will fix it for a UITableViewController (without any magic numbers). The only thing I couldn't get it to fix is if you are on a phone call, in which case the top of the tableView is pushed down too much. If anyone knows how to solve that, please let us know.

这将为 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
    }
}

回答by Hot Licks

I don't know how Kosher it is, but I found that this scheme moves the ViewController's view down and provides the status bar with a solid background:

我不知道它是如何 Kosher 的,但我发现这个方案将 ViewController 的视图向下移动并为状态栏提供了纯色背景:

- (void)viewDidLoad {
    [super viewDidLoad];

    // Shove everything down if iOS 7 or later
    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.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 redColor];
        [self.view addSubview:statusBar];
    }

Of course, replace redColorwith whatever color you want for the background.

当然,替换redColor为您想要的任何背景颜色。

You must separately do one of the swizzles to set the color of the characters/symbols in the status bar. I use View controller-based status bar appearance = NOand Status bar style = Opaque black stylein the plist, to do this globally.

您必须单独执行其中一项调整以设置状态栏中字符/符号的颜色。我在 plist 中使用View controller-based status bar appearance = NOStatus bar style = Opaque black style来全局执行此操作。

Seems to work, and I'd be interested to hear of any bugs or issues with it.

似乎有效,我很想知道它的任何错误或问题。