web-dev-qa-db-fra.com

Comment obtenir la taille réelle du cadre [UIScreen mainScreen]?

Je suis un peu ennuyé. J'ai une application avec la barre d'état visible dans la fenêtre principale. Étant donné que je voudrais configurer mes vues et leurs tailles d'image de manière dynamique (peut-être que la barre d'état prend 40 pixels pendant un appel téléphonique, par exemple).

Je peux faire l'un des deux:

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

Ce qui est vraiment ennuyeux, c'est que ces deux sorties produisent deux ensembles de valeurs différents, chacun étant également inutile.

bounds affichera: {{0, 0}, {320, 480}} tandis que
applicationFrame affichera {{0, 20}, {320, 460}}

Comme vous pouvez le voir, bounds donne l'origine y correcte (0 commence juste en dessous de la barre d'état) mais donne ensuite une hauteur de 480, ce qui est incorrect. Il devrait être de 460, car la barre d'état est visible. Ensuite, nous avons applicationFrame qui commence 20 pixels sous la barre d'état (donc il y a un plafond), mais donne ensuite la bonne hauteur. Mais ce n'est pas très utile quand il est ensuite abaissé de 20 pixels de toute façon.

De l'aide?

48
runmad

En fait, c'est très utile.
Lorsque vous demandez à un UIScreen car c'est Bounds vous obtenez les limites de l'écran, qui est tout l'écran de l'appareil. (la barre d'état fait partie de l'écran)
Mais si vous demandez à un UIScreen de vous dire où et quelle taille peut être la vue racine de votre application demandant le applicationFrame est utile. Il n'y a pas de relation directe entre les 2 appels sauf que le applicationFrame est retourné dans le UIScreen bounds système de coordonnées. (Mais la barre d'état ne fait pas partie de votre candidature, cela explique le résultat différent)

applicationFrame
Le rectangle de cadre à utiliser pour la fenêtre de votre application. (lecture seulement)
@ property (nonatomique, en lecture seule) CGRect applicationFrame
Discussion
Cette propriété contient les limites de l'écran moins la zone occupée par la barre d'état, si elle est visible. L'utilisation de cette propriété est la méthode recommandée pour récupérer la taille de fenêtre initiale de votre application. Le rectangle est spécifié en points.

50
Vincent Bernier

En fait, 0 ne démarre pas au bas de la barre d'état. Cela commence au sommet. Ajoutez un UILabel à (0,0) et vous ne le verrez pas à moins que la barre d'état ne soit cachée. Ainsi, les limites vous donnent la zone d'écran totale et applicationFrame vous donne la zone avec laquelle votre application doit travailler. Je parie que si vous cachez la barre d'état, le cadre d'application correspondra aux limites.

8
tupakapoor

J'ai eu un problème similaire. Ce que je faisais était plutôt stupide, mais j'espère que cela aide quelqu'un.

Dans la sous-vue, j'avais:

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

Parce que je créais ma sous-vue avec un cadre avec une origine pas à (0,0), mais en utilisant ensuite ce même cadre pour générer des sous-vues pour ma sous-vue, ces sous-vues ont également été déplacées vers le bas. Le résultat a été cette bannière noire agaçante que vous avez mentionnée.

J'ai résolu ce problème en procédant comme suit:

- (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

Mise à jour 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

Vous pourriez regarder UIWindow. Il hérite de UIView donc il aura des limites et un cadre, et les applications iOS sont toutes à fenêtre unique. - [UIApplication keyWindow] renverra la fenêtre configurée par le délégué de l'application. Puisque toutes les autres vues sont ancrées dans la fenêtre principale, j'imagine que cela devrait vous donner des limites correctes.

0
pzearfoss