私は少しイライラしています。メインウィンドウにステータスバーが表示されるアプリがあります。ビューとそのフレームサイズを動的に設定したいので(たとえば、通話中にステータスバーが40ピクセルを占有するなど)。
次の2つのいずれかを実行できます。
[[UIScreen mainScreen] bounds];
[[UIScreen mainScreen] applicationFrame];
本当に厄介なのは、これら2つの出力が2つの異なる値のセットを出力することであり、それぞれが同じように役に立たないということです。
bounds
は以下を出力します:{{0, 0}, {320, 480}}
whileapplicationFrame
は{{0, 20}, {320, 460}}
を出力します
ご覧のとおり、bounds
は正しいy原点(0はステータスバーのすぐ下から始まります)を提供しますが、高さ480を提供しますが、これは正しくありません。ステータスバーが表示されるため、460になります。次に、ステータスバーの下に20ピクセルで始まる(つまりキャップがある)applicationFrame
がありますが、正しい高さを与えます。しかし、とにかく20ピクセル押し下げられた場合、それはあまり役に立ちません。
何か助け?
実際、これは非常に便利です。UIScreen
にBounds
を要求すると、画面の境界が得られます。これはデバイス画面全体です。 (ステータスバーは画面の一部です)
ただし、UIScreen
を要求して、applicationFrame
を要求するアプリケーションのルートビューの場所と大きさを教えてください。 applicationFrame
がUIScreen bounds
座標系で返されることを除いて、2つの呼び出し間に直接的な関係はありません。 (ただし、ステータスバーはアプリケーションの一部ではなく、異なる結果を説明します)
applicationFrame
アプリケーションのウィンドウに使用するフレームの長方形。 (読み取り専用)
@ property(nonatomic、readonly)CGRect applicationFrame
討論
このプロパティには、画面の境界からステータスバーが表示されている場合、その領域を差し引いたものが含まれます。アプリケーションの初期ウィンドウサイズを取得するには、このプロパティを使用することをお勧めします。長方形はポイントで指定されます。
実際には、ステータスバーの下部から0は開始されません。それはその上部から始まります。 UILabelを(0,0)に追加すると、ステータスバーを非表示にしない限り表示されません。したがって、バウンドは画面全体の領域を提供し、applicationFrameはアプリケーションが動作する必要がある領域を提供します。ステータスバーを非表示にすると、アプリケーションフレームが境界に一致することに間違いはありません。
同様の問題がありました。私がやっていたことはかなり愚かだったが、これが誰かを助けることを願っています。
サブビューで私が持っていた:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
UIView * otherSubview = [[UIView alloc] initWithFrame:frame];
[self addSubview:otherSubview];
}
return self;
}
Origin not at(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;
}
Swift 2.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)
}
UIWindowを見るかもしれません。 UIViewを継承するため、境界とフレームがあり、iOSアプリはすべて単一のウィンドウです。 -[UIApplication keyWindow]は、アプリのデリゲートによって設定されたウィンドウを返します。他のすべてのビューはメインウィンドウに固定されているため、これにより正しい境界が得られるはずです。