2011-03-01 59 views
45

我有点恼火。我有一个应用程序的状态栏在主窗口中可见。因为我想动态设置我的视图和帧大小(例如,在通话期间状态栏占用40个像素)。如何获得实际的[UIScreen mainScreen]帧大小?

我能做到两者之一:

[[UIScreen mainScreen] bounds]; 
[[UIScreen mainScreen] applicationFrame]; 

的真的很烦人,这是这两个输出两组不同的值,每个同样无用。

bounds将输出:{{0, 0}, {320, 480}}
applicationFrame将输出{{0, 20}, {320, 460}}

正如你所看到的,bounds给出正确y原点但随后(右下方状态栏0开始)给出了480的高度,这是不正确。它应该是460,因为状态栏是可见的。然后我们有applicationFrame,它从状态栏下面20个像素开始(因此有一个上限),但是会给出正确的高度。但是,如果无论如何都会推低20个像素,这并不是很有用。

任何帮助?

+2

特别有用。在这种情况下,边界是物理玻璃屏幕,applicationFrame就是没有状态栏的边界。要清楚,它们都在** SAME坐标**,“玻璃”坐标中。所以边界开始(显然!)为零,而应用程序框架始于状态栏结束的位置 - 在19之后,即20! – 2012-09-14 01:37:47

+0

这是完全正确的,良好的交往时

func presentAboveAll() { //Get the view from the nib. Assuming the view is is in AboveAllView.xib let nibContents = NSBundle.mainBundle().loadNibNamed("AboveAllView", owner: nil, options: nil) //Get hold of your view let views = nibContents.filter { if let _ = $0 as? UIView{ return true } return false } guard views.count > 0 else { return } //Set up frame and add to the app's key window let view = views.first as! UIView view.frame = UIScreen.mainScreen().bounds UIApplication.sharedApplication().keyWindow?.addSubview(view) } 
Fattie 2013-12-04 17:10:10

+0

CGPoint p = [[UIScreen mainScreen] bounds] .origin; CGSize s = [[UIScreen mainScreen] applicationFrame] .size; CGRectMake(p.x,p.y,s.width,s.height);如果你真的想要一个的起源和另一个的大小。 – Kevin 2016-02-22 11:48:53

回答

49

其实这是非常有用的。
当你问一个UIScreen它的Bounds你会得到屏幕的界限,这是整个设备屏幕。 (状态栏是屏幕的一部分)
但是,如果您要求UIScreen告诉您在哪里以及有多大,您的应用程序的根视图要求applicationFrame是有用的。 除了在UIScreen bounds坐标系中返回applicationFrame之外,两个调用之间没有直接关系。(但状态栏是不是你的应用程序的一部分,解释不同的结果)

applicationFrame
框架矩形使用您的应用程序的窗口。 (只读)
@property(非原子,只读)CGRect应用程序框
讨论
该属性包含屏幕边界减去状态栏占用的区域(如果可见)。推荐使用此属性来检索应用程序的初始窗口大小。矩形用点表示。

+1

我使用iOS7(没有电话,热点或任何改变状态栏高度...)的iPhone 4上的[[UIScreen mainScreen] applicationFrame] .size.height'获得'460'。 'bounds'给了我'480'作为'height' ... – 2014-01-05 16:13:21

+0

@AvielGross谢谢,我不记得我以什么方式偶然发现在iOS7中有所不同(可能是iOS7的预发布版本,或者在一个非常糟糕的梦中......),但是我今天无法再现它,所以我已经更新了我的答案。再次感谢修正。 – 2014-01-06 00:43:12

0

你可能会看UIWindow。它从UIView继承,所以它会有边界和框架,iOS应用程序都是单个窗口。 - [UIApplication keyWindow]将返回由应用程序委托设置的窗口。由于所有其他视图都固定在主窗口中,我想这应该给你正确的界限。

8

实际上0不会从状态栏的底部开始。它从顶部开始。在(0,0)处添加UILabel,除非隐藏状态栏,否则不会看到它。所以边界为您提供了总屏幕区域,applicationFrame为您提供了应用程序必须使用的区域。我敢打赌,如果你隐藏状态栏,应用程序框架将与界限相匹配。

1

我有类似的问题。我所做的很愚蠢,但我希望这可以帮助某人。

在子视图我有:

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     UIView * otherSubview = [[UIView alloc] initWithFrame:frame]; 
     [self addSubview:otherSubview]; 
    } 
    return self; 
} 

因为我创造我有框架子视图与原(0,0),但是如果使用的是相同的帧生成子视图我子视图,这些子视图也被转移下来。结果是你提到的令人讨厌的黑色旗帜。

我解决了这个问题通过执行以下操作:

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     CGRect rect = frame; 
     rect.origin.x = 0; 
     rect.origin.y = 0; 
     UIView * otherSubview = [[UIView alloc] initWithFrame:rect]; 
     [self addSubview:otherSubview]; 
    } 
    return self; 
} 
-1

雨燕2.0更新:

与iPhone 5
相关问题