web-dev-qa-db-ja.com

実際の[UIScreen mainScreen]フレームサイズを取得する方法

私は少しイライラしています。メインウィンドウにステータスバーが表示されるアプリがあります。ビューとそのフレームサイズを動的に設定したいので(たとえば、通話中にステータスバーが40ピクセルを占有するなど)。

次の2つのいずれかを実行できます。

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

本当に厄介なのは、これら2つの出力が2つの異なる値のセットを出力することであり、それぞれが同じように役に立たないということです。

boundsは以下を出力します:{{0, 0}, {320, 480}} while
applicationFrame{{0, 20}, {320, 460}}を出力します

ご覧のとおり、boundsは正しいy原点(0はステータスバーのすぐ下から始まります)を提供しますが、高さ480を提供しますが、これは正しくありません。ステータスバーが表示されるため、460になります。次に、ステータスバーの下に20ピクセルで始まる(つまりキャップがある)applicationFrameがありますが、正しい高さを与えます。しかし、とにかく20ピクセル押し下げられた場合、それはあまり役に立ちません。

何か助け?

48
runmad

実際、これは非常に便利です。
UIScreenBoundsを要求すると、画面の境界が得られます。これはデバイス画面全体です。 (ステータスバーは画面の一部です)
ただし、UIScreenを要求して、applicationFrameを要求するアプリケーションのルートビューの場所と大きさを教えてください。 applicationFrameUIScreen bounds座標系で返されることを除いて、2つの呼び出し間に直接的な関係はありません。 (ただし、ステータスバーはアプリケーションの一部ではなく、異なる結果を説明します)

applicationFrame
アプリケーションのウィンドウに使用するフレームの長方形。 (読み取り専用)
@ property(nonatomic、readonly)CGRect applicationFrame
討論
このプロパティには、画面の境界からステータスバーが表示されている場合、その領域を差し引いたものが含まれます。アプリケーションの初期ウィンドウサイズを取得するには、このプロパティを使用することをお勧めします。長方形はポイントで指定されます。

50
Vincent Bernier

実際には、ステータスバーの下部から0は開始されません。それはその上部から始まります。 UILabelを(0,0)に追加すると、ステータスバーを非表示にしない限り表示されません。したがって、バウンドは画面全体の領域を提供し、applicationFrameはアプリケーションが動作する必要がある領域を提供します。ステータスバーを非表示にすると、アプリケーションフレームが境界に一致することに間違いはありません。

8
tupakapoor

同様の問題がありました。私がやっていたことはかなり愚かだったが、これが誰かを助けることを願っています。

サブビューで私が持っていた:

- (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;
}
1
LDY

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)
}
0
Shripada

UIWindowを見るかもしれません。 UIViewを継承するため、境界とフレームがあり、iOSアプリはすべて単一のウィンドウです。 -[UIApplication keyWindow]は、アプリのデリゲートによって設定されたウィンドウを返します。他のすべてのビューはメインウィンドウに固定されているため、これにより正しい境界が得られるはずです。

0
pzearfoss