2011-03-01 39 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
相關問題