ios 解释 iOS7 中自动调整滚动视图插入、扩展布局包括OpaqueBars、边缘ForExtendedLayout 之间的区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18798792/
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
Explaining difference between automaticallyAdjustsScrollViewInsets, extendedLayoutIncludesOpaqueBars, edgesForExtendedLayout in iOS7
提问by user1010819
I have been reading a lot about iOS7 UI transition.
我已经阅读了很多关于 iOS7 UI 转换的内容。
I am not able to get what these three properties automaticallyAdjustsScrollViewInsets
, extendedLayoutIncludesOpaqueBars
, edgesForExtendedLayout
??
我不能够得到什么这三个属性automaticallyAdjustsScrollViewInsets
,extendedLayoutIncludesOpaqueBars
,edgesForExtendedLayout
?
For example I am trying to make my view controllers start below the status bar but I am not able to achieve it.
例如,我试图让我的视图控制器从状态栏下方开始,但我无法实现它。
回答by Antonio MG
Starting in iOS7, the view controllers use full-screen layout by default. At the same time, you have more control over how it lays out its views, and that's done with those properties:
从 iOS7 开始,视图控制器默认使用全屏布局。同时,您可以更好地控制它的视图布局方式,这是通过这些属性完成的:
edgesForExtendedLayout
edgeForExtendedLayout
Basically, with this property you set which sides of your view can be extended to cover the whole screen. Imagine that you push a UIViewController
into a UINavigationController
. When the view of that view controller is laid out, it will start where the navigation bar ends, but this property will set which sides of the view (top, left, bottom, right) can be extended to fill the whole screen.
基本上,您可以使用此属性设置视图的哪一边可以扩展以覆盖整个屏幕。想象一下,您将 a 推UIViewController
入 a UINavigationController
。当该视图控制器的视图布局时,它将从导航栏结束的地方开始,但此属性将设置视图的哪一侧(顶部、左侧、底部、右侧)可以扩展以填充整个屏幕。
Let see it with an example:
让我们看一个例子:
UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = [UIColor redColor];
UINavigationController *mainNavigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
Here you are not setting the value of edgesForExtendedLayout
, therefore the default value is taken (UIRectEdgeAll
), so the view extends its layout to fill the whole screen.
此处您没有设置 的值edgesForExtendedLayout
,因此采用默认值 ( UIRectEdgeAll
),因此视图扩展其布局以填充整个屏幕。
This is the result:
这是结果:
As you can see, the red background extends behind the navigation bar and the status bar.
如您所见,红色背景延伸到导航栏和状态栏的后面。
Now, you are going to set that value to UIRectEdgeNone
, so you are telling the view controller to not extend the view to cover the screen:
现在,您将该值设置为UIRectEdgeNone
,因此您告诉视图控制器不要扩展视图以覆盖屏幕:
UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = [UIColor redColor];
viewController.edgesForExtendedLayout = UIRectEdgeNone;
UINavigationController *mainNavigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
And the result:
结果:
automaticallyAdjustsScrollViewInsets
自动调整ScrollViewInsets
This property is used when your view is a UIScrollView
or similar, like a UITableView
. You want your table to start where the navigation bar ends, because you wont see the whole content if not, but at the same time you want your table to cover the whole screen when scrolling. In that case, setting edgesForExtendedLayout
to None won't work because your table will start scrolling where the navigation bar ends and it wont go behind it.
当您的视图为 aUIScrollView
或类似视图时使用此属性,例如 a UITableView
。您希望您的表格从导航栏结束的地方开始,因为否则您将看不到整个内容,但同时您希望您的表格在滚动时覆盖整个屏幕。在这种情况下,设置edgesForExtendedLayout
为 None 将不起作用,因为您的表格将在导航栏结束的地方开始滚动并且不会在它后面滚动。
Here is where this property comes in handy, if you let the view controller automatically adjust the insets (setting this property to YES, also the default value) it will add insets to the top of the table, so the table will start where the navigation bar ends, but the scroll will cover the whole screen.
这是这个属性派上用场的地方,如果你让视图控制器自动调整插图(将此属性设置为 YES,也是默认值)它会在表格的顶部添加插图,所以表格将从导航开始bar 结束,但滚动将覆盖整个屏幕。
This is when is set to NO:
这是当设置为NO:
And YES (by default):
是(默认情况下):
In both cases, the table scrolls behind the navigation bar, but in the second case (YES), it will start from below the navigation bar.
在这两种情况下,表格都在导航栏后面滚动,但在第二种情况下(是),它将从导航栏下方开始。
extendedLayoutIncludesOpaqueBars
extendedLayoutIncludesOpaqueBars
This value is just an addition to the previous ones. By default, this parameter is set to NO. If the status bar is opaque, the views won't be extended to include the status bar, even if you extend your view to cover it (edgesForExtendedLayout
to UIRectEdgeAll
).
此值只是对先前值的补充。默认情况下,该参数设置为 NO。如果状态栏不透明,则视图不会扩展以包含状态栏,即使您扩展视图以覆盖它(edgesForExtendedLayout
to UIRectEdgeAll
)。
If you set the value to YES, this will allow the view to go underneath the status bar again.
如果您将该值设置为 YES,这将允许视图再次进入状态栏下方。
If something is not clear, write a comment and I'll answer it.
如果有什么不清楚的,写评论,我会回答。
How does iOS know what UIScrollView to use?
iOS 如何知道使用什么 UIScrollView?
iOS grabs the first subview in your ViewController's view, the one at index 0, and if it's a subclass of UIScrollView
then applies the explained properties to it.
iOS 获取 ViewController 视图中的第一个子视图,即索引 0 处的子视图,如果它是 的子类,UIScrollView
则将解释的属性应用于它。
Of course, this means that UITableViewController
works by default (since the UITableView
is the first view).
当然,这意味着UITableViewController
默认情况下有效(因为这UITableView
是第一个视图)。
回答by Ali Beadle
Not sure if you are using storyboards, but if you are, to make your view controllers start below the status bar (and above the bottom bar):
不确定您是否正在使用故事板,但如果是,让您的视图控制器从状态栏下方(和底部栏上方)开始:
Select the view controller in IB, In the attributes inspector, deselect 'Extend Edges - Under Top Bars' and 'Extend Edges - Under Bottom Bars'.
在 IB 中选择视图控制器,在属性检查器中,取消选择“Extend Edges - Under Top Bars”和“Extend Edges - Under Bottom Bars”。
回答by Christopher Wade Cantley
I am using storyboards and using the above advice worked however I wasn't exactly sure how to implement it. Below is a short example in swift of how it cleared up the problem by putting the recommended solution into the ViewController.
我正在使用故事板并使用上述建议有效,但我不确定如何实现它。下面是一个简短的例子,它是如何通过将推荐的解决方案放入 ViewController 来解决问题的。
import Foundation
import UIKit
// This ViewController is connected to a view on a storyboard that
// has a scrolling sub view.
class TheViewController: UIViewController {
// Prepares the view prior to loading. Putting it in viewDidAppear didn't work.
override func viewWillAppear(animated: Bool) {
// this method is an extension of the UIViewController
// so using self works as you might expect.
self.automaticallyAdjustsScrollViewInsets = false
// Default is "true" so this sets it to false tells it to use
// the storyboard as you have it placed
// and not how it thinks it should place it.
}
}
My Problem:
Auto Adjust set to true by default causing a difference between storyboard design and simulator
我的问题:默认情况下自动调整设置为 true 导致故事板设计和模拟器之间存在差异
Resolved:
Code above applied, turning off the auto-adjust.
已解决:应用上述代码,关闭自动调整。
回答by user3430340
I solved this problem by adding this line, but my problem was related to a UIView
, not UIScrollView
我通过添加这一行解决了这个问题,但我的问题与 a 相关UIView
,而不是UIScrollView
self.navigationController.navigationBar.translucent = NO;
回答by Vojta Rujbr
Just bare in mind that
automaticallyAdjustsScrollViewInsets
property works only if some kind of scroll view (table view, collection view,...) is either
请记住,
automaticallyAdjustsScrollViewInsets
只有在某种滚动视图(表视图、集合视图...)
- The view of VC, or
- First subview of this view
- VC的观点,或
- 此视图的第一个子视图
Other suggested, that it doest work even if it is the first subview, but there are other scroll views in the view hierarchy.
其他人建议,即使它是第一个子视图,它也不起作用,但视图层次结构中还有其他滚动视图。
EDIT (extension DIY)
编辑(扩展DIY)
If you want similar behaviour even if you can't fulfil these conditions (e.g. you have a background image below the scroll view), you can adjust the scroll view insets manually. But please don't set it to constant like 44 or 64 or even 20 like many suggest around SO. You can't know the size ever. There can be the incall/gps/audio notification, navigation bar doesn't have to be always 44 pts etc.
如果即使您无法满足这些条件(例如您在滚动视图下方有背景图像)也想要类似的行为,您可以手动调整滚动视图插图。但是请不要像许多人建议的那样将其设置为 44 或 64 甚至 20 等常量。你永远不知道尺寸。可以有 incall/gps/audio 通知,导航栏不必总是 44 pts 等。
I think the best solution is to use layoutGuide length
in didLayoutSubviews:
我认为最好的解决方案是在 didLayoutSubviewslength
中使用layoutGuide:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.contentInset = UIEdgeInsets(top: topLayoutGuide.length, left: 0, bottom: 0, right: 0)
scrollView.scrollIndicatorInsets = scrollView.contentInset
}
You can use the bottomLayoutGuide in the same way.
您可以以相同的方式使用 bottomLayoutGuide。