iOS 7: UITableView s'affiche sous la barre d'état

219

Le premier écran de mon application est UITableViewControllersans barre de navigation, ce qui signifie que le contenu passe sous la barre d'état, il y a donc beaucoup de collisions de texte. J'ai ajusté les propriétés Under top barset celles Adjust scroll view insetsqui l'empêchent de défiler sous, mais au prix de garder le haut de la vue de la table sous. J'ai essayé de définir le UITableViewcadre pour qu'il soit décalé de 20 pixels, mais il ne semble pas prendre effet et, comme j'ai actuellement besoin que l'application soit compatible avec iOS 6, je ne peux pas passer aux storyboards iOS 7 pour forcer la mise en page automatique à utiliser le guide de hauteur supérieur. Quelqu'un a-t-il trouvé une solution qui fonctionne pour les deux versions?

Ce que j'ai essayé: définir edgesForExtendedLayout, modifier les paramètres dans Storyboard pour Under top barset Adjust scroll viewforcer le cadre dans une nouvelle zone.

Une image vaut mieux que mille mots: Flux de barre d'état sous

Nicholas Smith
la source
2
Une solution rapide pourrait être d'ajouter un en-tête vierge de 20 pixels à la table lors de l'exécution sur iOS 7.
EricS
@EricS: J'ai déjà un en- UITableViewtête dedans, il coule également sous la barre d'état.
Nicholas Smith
Pourquoi ne pas utiliser le guide de mise en page automatique sur iOS 6? Ça marche.
Steven Fisher

Réponses:

366

Pour toute personne intéressée à répliquer cela, suivez simplement ces étapes:

  1. Créer un nouveau projet iOS
  2. Ouvrez le storyboard principal et supprimez la valeur par défaut / initiale UIViewController
  3. Faites glisser un nouveau UITableViewControllerdepuis la bibliothèque d'objets
  4. Définissez-le comme contrôleur de vue initial
  5. Nourrir le tableau des données de test

Si vous suivez les étapes ci-dessus, lorsque vous exécutez l'application, vous verrez que rien, y compris le fait de modifier les cases à cocher de Xcode pour "étendre les bords sous les barres {haut, bas, opaques}", empêche la première ligne d'apparaître sous la barre d'état, vous ne pouvez pas non plus résoudre ce problème par programme.

Par exemple, dans le scénario ci-dessus, les éléments suivants n'auront aucun effet:

// These do not work
self.edgesForExtendedLayout=UIRectEdgeNone;
self.extendedLayoutIncludesOpaqueBars=NO;
self.automaticallyAdjustsScrollViewInsets=NO;

Ce problème peut être très frustrant, et je pense que c'est un bug de la part d'Apple, surtout parce qu'il apparaît dans leur propre pré-câblé à UITableViewControllerpartir de la bibliothèque d'objets.

Je suis en désaccord avec tous ceux qui essaient de résoudre ce problème en utilisant n'importe quelle forme de «nombres magiques», par exemple «utiliser un delta de 20 pixels». Ce type de programmation étroitement couplée n'est certainement pas ce qu'Apple veut que nous fassions ici.

J'ai découvert deux solutions à ce problème:

  • Préserver la UITableViewControllerscène de :
    Si vous souhaitez conserver le UITableViewControllerdans le storyboard, sans le placer manuellement dans une autre vue, vous pouvez incorporer le UITableViewControllerdans un UINavigationController(Editeur> Intégrer dans> Contrôleur de navigation) et décochez "Affiche la barre de navigation" dans l'inspecteur . Cela résout le problème sans aucun ajustement supplémentaire nécessaire, et il préserve également votre UITableViewControllerscène dans le storyboard.

  • Utiliser AutoLayout et incorporer le UITableViewdans une autre vue (je pense que c'est ainsi qu'Apple veut que nous le fassions) :
    Créez un vide UIViewControlleret faites-le glisser UITableViewdedans. Ensuite, faites glisser la touche Ctrl de votre UITableViewvers la barre d'état. Lorsque la souris arrive en bas de la barre d'état, vous verrez une bulle de mise en page automatique indiquant "Top Layout Guide". Relâchez la souris et choisissez "Espacement vertical". Cela indiquera au système de disposition de le placer juste en dessous de la barre d'état.

J'ai testé les deux façons sur une application vide et ils fonctionnent tous les deux. Vous devrez peut-être effectuer quelques ajustements supplémentaires pour les faire fonctionner pour votre projet.

marinosb
la source
5
Pour info, l'option 1 (intégration dans un contrôleur de navigation) fait que les cellules sont visibles derrière la barre d'état translucide lorsque vous faites défiler le tableau.
RyanR
4
@RyanR Je l'ai remarqué aussi, mais je pense que c'est OK à un moment donné. Apple a fait la même chose dans la vue des onglets ouverts de Safari mobile, les onglets seront affichés sous la barre d'état. La solution de contrôleur de navigation est la solution de contournement la plus simple, j'en profite. Cependant, la barre d'état translucide est une idée stupide.
Pride Chung
6
Lorsque je fais le contrôle-glisser de la table vers le haut, je ne rencontre jamais la barre d'état. Il n'y a pas de barre d'état visible dans la vue, je ne sais pas ce que vous voulez dire ici ...
Jesse
4
L'option 2 ne fonctionne plus dans Xcode 5. L'action décrite (ctrl-glisser) n'aurait jamais dû fonctionner, car elle appartient au système Outlets, mais même si vous faites glisser manuellement vers l'arborescence de la scène à gauche, le guide de disposition supérieur NE FONCTIONNE PAS (ça devrait le faire, AFAICT - Je pense que c'est encore un autre bug majeur dans AutoLayout :( :()
Adam
3
@PrideChung ça a l'air stupide quand on utilise un en-tête avec la tableview, l'en-tête reste fixe en haut et les éléments disparaîtront derrière - et réapparaîtront derrière la barre d'état transparente ...
Ixx
86

Si vous faites des choses par programme et utilisez un UITableViewControllersans un, UINavigationControllervotre meilleur pari est de faire ce qui suit dans viewDidLoad:

Swift 3

self.tableView.contentInset = UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 0)

Swift plus tôt

self.tableView.contentInset = UIEdgeInsetsMake(20.0f, 0.0f, 0.0f, 0.0f);

Le UITableViewControllerdéfilera toujours derrière la barre d'état mais ne sera pas en dessous lorsqu'il défilera vers le haut.

lipka
la source
1
Vous pouvez ajouter une vérification pour la version du système d'exploitation> 7 et prendre en charge les systèmes d'exploitation plus anciens (pas d'encart pour ceux-ci). Sinon, cela a bien fonctionné pour mes besoins.
SimpsOff
8
La valeur de la hauteur de codage en dur n'est pas la meilleure idée.
Maciej Kozieł
3
Oui, utilisez topLayoutGuideplutôt la longueur.
lipka
10
J'utiliserais UIApplication.sharedApplication.statusBarFrame.size.heightau lieu de 20.
mojuba
Cela a été mis à jour vers UIApplication.shared.statusBarFrame.size.height ces jours-ci.
asetniop
23

Veuillez noter: cela a fonctionné pour moi pour la configuration suivante:

  • Pas de barre de navigation en haut de l'écran (la vue du tableau rencontre la barre d'état)
  • La vue de table ne défile pas

Si les deux conditions ci-dessus ne sont pas remplies, votre kilométrage peut varier.

Message d'origine

J'ai créé ma vue par programme et cela a fini par fonctionner pour moi:

- (void) viewDidLayoutSubviews {
    // only works for iOS 7+
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
        CGRect viewBounds = self.view.bounds;
        CGFloat topBarOffset = self.topLayoutGuide.length;

        // snaps the view under the status bar (iOS 6 style)
        viewBounds.origin.y = topBarOffset * -1;

        // shrink the bounds of your view to compensate for the offset
        viewBounds.size.height = viewBounds.size.height + (topBarOffset * -1);
        self.view.bounds = viewBounds;
    }
}

Source (dans la section topLayoutGuide au bas de la page 39).

Stunner
la source
Intéressant ... J'ai pu l'appeler ainsi dans mon projet sans aucun problème ... J'ai peut-être une structure de mise en page plus simple que la vôtre. Votre suggestion est correcte, je vais apporter ce changement dans ma réponse.
Stunner
Je suis tombé sur le problème lorsque j'ai tourné mon application. Si la rotation était désactivée, vous n'auriez probablement pas de problème.
Jeremy
Je n'ai pas activé la rotation dans mon projet et je suis tombé sur le problème, mais oui, toujours un bon point.
Stunner
1
Pour tous ceux qui implémentent leur propre contrôleur de conteneur, c'est la bonne façon d'ajuster le statut ou la barre de navigation sous-jacente!
Rafael Nobre
Si vous modifiez l'origine, mais pas la hauteur des limites de la vue, le fond ne sera-t-il pas rogné par le bord inférieur de l'écran du montant que vous avez modifié l'origine? (il devient donc impossible de voir les dernières rangées de pixels)
Tenfour04
20

Ajout à la première réponse:

après que la 2ème méthode ne semblait pas fonctionner au départ, j'ai fait quelques bricolages supplémentaires et j'ai trouvé la solution.

TLDR; la deuxième solution de la réponse la plus efficace fonctionne presque, mais pour certaines versions de xCode, ctrl + glisser vers "Top Layout Guide" et sélectionner Vertical Spacing ne fait rien. Cependant, en ajustant d'abord la taille de la vue Table puis en sélectionnant "Top Space to Top Layout Guide" fonctionne


  1. Faites glisser un ViewController vierge sur le storyboard. Contrôleur de vue

  2. Faites glisser un objet UITableView dans la vue. (Pas UITableViewController). Positionnez-le au centre à l'aide des guides de disposition bleus.

Vue de tableau Image centrale

  1. Faites glisser un UITableViewCell dans le TableView. Ce sera votre prototype de cellule de réutilisation, alors n'oubliez pas de définir son identifiant de réutilisation sous l'onglet Attributs ou vous obtiendrez un plantage.

Ajouter une cellule de vue de tableau Réutiliser l'identifiant

  1. Créez votre sous-classe personnalisée d'UIViewController et ajoutez les <UITableViewDataSource, UITableViewDelegate>protocoles. N'oubliez pas de définir le ViewController de votre storyboard sur cette classe dans l'inspecteur d'identité.

  2. Créez une sortie pour votre TableView dans votre fichier d'implémentation et nommez-la "tableView"

Créer un débouché Vue de tableau

  1. Cliquez avec le bouton droit sur TableView et faites glisser à la fois le dataSource et le délégué vers votre ViewController.

délégué dataSource

Maintenant, pour la partie de ne pas couper dans la barre d'état.

  1. Saisissez le bord supérieur de votre vue Tableau et déplacez-le vers le bas vers l'un des guides de disposition automatique en pointillés bleus qui se trouvent près du haut

redimensionner

  1. Maintenant, vous pouvez contrôler le glissement de la vue tabulaire vers le haut et sélectionner Top Space to Top Layout Guide

Guide de disposition Top Space to Top

  1. Il vous donnera une erreur sur la disposition ambiguë de TableView, ajoutez simplement des contraintes manquantes et votre terminé.

Ajouter des contraintes manquantes

Vous pouvez maintenant configurer votre vue de table comme d'habitude, et cela n'attachera pas la barre d'état!

ErikAGriffin
la source
11
- (void) viewDidLayoutSubviews {
    if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
        self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;
        if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
            self.edgesForExtendedLayout = UIRectEdgeNone;   // iOS 7 specific
        CGRect viewBounds = self.view.bounds;
        CGFloat topBarOffset = self.topLayoutGuide.length;
        viewBounds.origin.y = topBarOffset * -1;
        self.view.bounds = viewBounds;
        self.navigationController.navigationBar.translucent = NO;
    }
}

https://developer.apple.com/library/ios/documentation/userexperience/conceptual/TransitionGuide/SupportingEarlieriOS.html#//apple_ref/doc/uid/TP40013174-CH14-SW1

Olzh
la source
2
basculez <= vers> et supprimez le bloc if vide
pfrank
1
La lecture self.topLayoutGuide.lengthde viewDidLayoutSubviewsva bousiller la disposition des vues enfants.
@OLzh pendant que vous le décrivez, self.tableView ne peut pas défiler.
DawnSong
8

Sélectionnez UIViewController sur votre storyboard et décochez l'option Étendre les bords sous les barres supérieures. A travaillé pour moi. :)

cheville
la source
Hélas, ça n'a pas marché pour moi. UITableViewController complètement par défaut chevauche toujours la barre d'état. Je ne pense pas que la barre d'état compte comme une barre supérieure. Juste des barres de navigation et des tabulations.
Andrew Duncan
La seule solution qui fonctionne pour moi, ty. (Notez que vous devez "raccourcir" la vue sous la barre d'état dans IB et mettre à jour les contraintes).
Martin Makarsky
A travaillé pour moi sur Xcode 8 avec un UITableViewController.
Edouard Barbier
8

Voici comment l'écrire dans "Swift" Un ajustement à la réponse de @ lipka:

tableView.contentInset = UIEdgeInsetsMake(20.0, 0.0, 0.0, 0.0)
uplearnedu.com
la source
N'est-ce pas rapide autorisé ici?
uplearnedu.com
Seule solution qui a fonctionné pour moi, qui ne me fait pas créer un UIVIewController
Shereef Marzouk
1
Ceci est loin d'être idéal car il maintient l'encart supérieur à 20, même en paysage où il n'y a pas de barre d'état par défaut dans ios8
voidref
Cette variation gère bien n'importe quelle configuration pour moi:- (void)viewDidLayoutSubviews { if (self.tableView.contentInset.top != self.topLayoutGuide.length) { self.tableView.contentInset = UIEdgeInsetsMake(self.topLayoutGuide.length, 0.0, 0.0, 0.0); } }
qix
5

Pour Xcode 7, décocher la coche «translucide» de la barre de navigation a fonctionné pour moi.

entrez la description de l'image ici

David T
la source
Le plus simple, le plus rapide, le plus simple, le plus sûr? Solution. Je ne sais pas pourquoi cela a si peu de votes positifs par rapport à tout le reste.
Gruntcakes
3

Cela le corrigera pour un UITableViewController (sans aucun nombre magique). La seule chose que je n'ai pas pu résoudre, c'est si vous êtes en conversation téléphonique, auquel cas le haut de la tableView est trop enfoncé. Si quelqu'un sait comment résoudre ce problème, veuillez nous le faire savoir.

class MyTableViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()    
        configureTableViewTop()
    }

    override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
        coordinator.animateAlongsideTransition({ (context) -> Void in
            }, completion: { (context) -> Void in
                self.configureTableViewTop()
        })
    }

    func configureTableViewTop() { 
        tableView.contentInset.top = UIApplication.sharedApplication().statusBarFrame.height
    }
}
Harris
la source
2

Je ne sais pas à quel point il est casher, mais j'ai constaté que ce schéma déplace la vue du ViewController vers le bas et fournit la barre d'état avec un arrière-plan solide:

- (void)viewDidLoad {
    [super viewDidLoad];

    // Shove everything down if iOS 7 or later
    float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
    if (systemVersion >= 7.0f) {

        // Move the view down 20 pixels
        CGRect bounds = self.view.bounds;
        bounds.origin.y -= 20.0;
        [self.view setBounds:bounds];

        // Create a solid color background for the status bar
        CGRect statusFrame = CGRectMake(0.0, -20.0, bounds.size.width, 20);
        UIView* statusBar = [[UIView alloc] initWithFrame:statusFrame];
        statusBar.backgroundColor = [UIColor redColor];
        [self.view addSubview:statusBar];
    }

Bien sûr, remplacez-le redColorpar la couleur que vous souhaitez pour l'arrière-plan.

Vous devez effectuer séparément l'un des swizzles pour définir la couleur des caractères / symboles dans la barre d'état. J'utilise View controller-based status bar appearance = NOet Status bar style = Opaque black styledans la liste, pour le faire globalement.

Semble fonctionner, et je serais intéressé d'entendre des bugs ou des problèmes avec elle.

Hot Licks
la source
2

La réponse de chappjc fonctionne très bien lorsque vous travaillez avec des XIB.

J'ai trouvé que la solution la plus propre lors de la création par programme de TableViewControllers consiste à envelopper l'instance UITableViewController dans un autre UIViewController et à définir des contraintes en conséquence.

C'est ici:

UIViewController *containerLeftViewController = [[UIViewController alloc] init];
UITableViewController *tableViewController = [[UITableViewController alloc] init];

containerLeftViewController.view.backgroundColor = [UIColor redColor];

hostsAndMoreTableViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
[containerLeftViewController.view addSubview:tableViewController.view];

[containerLeftViewController addChildViewController:tableViewController];
[tableViewController didMoveToParentViewController:containerLeftViewController];

NSDictionary * viewsDict = @{ @"tableView": tableViewController.view ,
                              @"topGuide": containerLeftViewController.topLayoutGuide,
                              @"bottomGuide": containerLeftViewController.bottomLayoutGuide,
                              };
[containerLeftViewController.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[tableView]|"
                                                                                         options:0
                                                                                         metrics:nil
                                                                                           views:viewsDict]];
[containerLeftViewController.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[topGuide][tableView][bottomGuide]"
                                                                                         options:0
                                                                                         metrics:nil
                                                                                           views:viewsDict]];

À la vôtre, Ben

bhr
la source
1

Je pense que l'approche de l'utilisation de UITableViewController pourrait être un peu différente de ce que vous avez fait auparavant. Cela a fonctionné pour moi, mais vous n'en êtes peut-être pas fan. Ce que j'ai fait, c'est avoir un contrôleur de vue avec une vue de conteneur qui pointe vers mon UItableViewController. De cette façon, je suis en mesure d'utiliser le TopLayoutGuide fourni avec mon in storyboard. Ajoutez simplement la contrainte à la vue du conteneur et vous devriez être pris en charge pour iOS7 et iOS6.

Phong Le
la source
1

J'ai fini par utiliser une vue supplémentaire avec l'arrière-plan souhaité, ajoutée après TableView et placée sous la barre d'état:

    self.CoverView = [[UIView alloc]init];

    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {

    self.CoverView.frame = CGRectMake(0,0,self.view.bounds.size.width,20);
    }

    self.CoverView.backgroundColor = [UIColor whiteColor];
    self.TableView = [[UITableView alloc]initWithFrame:CGRectMake(0,
    self.CoverView.bounds.size.height,XXX, YYY)];
    [self.view addSubview:self.TableView];
    [self.view addSubview:self.CoverView];

Ce n'est pas très joli, mais c'est une solution assez simple, si vous avez besoin de travailler avec des vues sans xib, et à la fois IOS6 et IOS7

lilislilit
la source
1

J'ai fait cela pour l'affichage Retina / Non-Retina comme

BOOL isRetina = FALSE;

if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
    if ([[UIScreen mainScreen] scale] == 2.0) {
        isRetina = TRUE;
    } else {
        isRetina = FALSE;
    }
}

if (isRetina) {
    self.edgesForExtendedLayout=UIRectEdgeNone;
    self.extendedLayoutIncludesOpaqueBars=NO;
    self.automaticallyAdjustsScrollViewInsets=NO;
}
MaxEcho
la source
1

La solution suivante fonctionne assez bien dans le code sans utiliser de constantes magiques et tient compte du fait que l'utilisateur change la classe de taille, par exemple via des rotations ou des applications côte à côte sur les iPad:

- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
    [super traitCollectionDidChange:previousTraitCollection];
    // Fix up content offset to ensure the tableview isn't underlapping the status bar.
    self.tableView.contentInset = UIEdgeInsetsMake(self.topLayoutGuide.length, 0.0, 0.0, 0.0);
}
qix
la source
1

Fonctionne pour swift 3 - In viewDidLoad ();

let statusBarHeight = UIApplication.shared.statusBarFrame.height

let insets = UIEdgeInsets(top: statusBarHeight, left: 0, bottom: 0, right: 0)
tableView.contentInset = insets
tableView.scrollIndicatorInsets = insets

Ce code: 1. Obtient la hauteur de la barre d'état 2. Donne au haut de la vue de table un encart de contenu égal à la hauteur de la barre d'état. 3. Indique à l'indicateur de défilement le même encart, il apparaît donc sous la barre d'état.

Wesh RaphLola
la source
1

Pour ceux comme moi qui préfèrent ne pas intégrer leur UITableViewControllerdans un UIViewControlleressai ceci:

Une UITableViewControllersous-classe personnalisée peut ajouter une vue de masque à la vue d'ensemble de tableView. Ajoutez le masque sur viewDidAppear et supprimez le masque sur viewWillDisappear.

private var statusBarMaskView: UIView!

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    if let superview = self.tableView.superview {
        self.statusBarMaskView = UIView(frame: CGRect.zero)
        superview.insertSubview(self.statusBarMaskView, aboveSubview: self.tableView)
        self.statusBarMaskView.backgroundColor = self.tableView.backgroundColor

        // using a nice constraint layout library to set the frame
        self.statusBarMaskView.pinTop(to: superview)
        self.statusBarMaskView.pinLeft(to: superview)
        self.statusBarMaskView.pinRight(to: superview)
        self.statusBarMaskView.addHeightConstraint(with: 22.0)
        ////
    }
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    self.statusBarMaskView.removeFromSuperview()
    self.statusBarMaskView = nil
}
Lee Irvine
la source
0

J'avais un UISearchBar en haut de mon UITableView et les éléments suivants ont fonctionné;

self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0);
self.tableView.contentOffset = CGPointMake(0, -20);

Partagez et profitez ...

Sam T
la source
0

Je l'ai fait fonctionner en définissant la taille sur la forme libre

entrez la description de l'image ici

fengd
la source
2
Les «métriques simulées» ne s'appliquent qu'à voir votre création dans Xcode, pas la réalité. [Voir: stackoverflow.com/questions/16279379/…
Tyler A.
0

La solution d'Abrahamchez https://developer.apple.com/library/ios/qa/qa1797/_index.html a fonctionné pour moi comme suit. J'avais un seul UITableviewcontroller comme vue initiale. J'avais essayé le code offset et l'incorporation dans un navcon mais aucun des deux n'avait résolu la transparence de la barre d'état.

Ajoutez un Viewcontroller et faites-en la vue initiale. Cela devrait vous montrer des guides de mise en page supérieurs et inférieurs critiques.

Faites glisser l'ancienne Tableview dans la vue du nouveau contrôleur.

Faites tout le nécessaire pour installer la table dans le nouveau contrôleur:

Modifiez votre ancien fichier view controller.h pour hériter / sous-classe de UIViewController au lieu de UITableViewController.

Ajoutez UITableViewDataSource et UITableViewDelegate au .h du viewcontroller.

Reconnectez tout ce dont vous avez besoin dans le storyboard, comme une barre de recherche.

La grande chose est de mettre en place les contraintes, comme dans le Q&A d'Apple. Je n'ai pas pris la peine d'insérer une barre d'outils. Pas certain de la séquence exacte. Mais une icône rouge est apparue sur les guides de mise en page, peut-être lorsque j'ai construit. J'ai cliqué dessus et j'ai laissé Xcode installer / nettoyer les contraintes.

Ensuite, j'ai cliqué partout jusqu'à ce que je trouve la contrainte d'espace vertical et change sa valeur supérieure de -20 à 0 et cela fonctionne parfaitement.

Jack Bellis
la source
0

J'utilise un UISplitViewController avec un navigationcontroller et un tableviewcontroller. Cela a fonctionné pour moi dans la vue principale après avoir essayé de nombreuses solutions ici:

float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if (systemVersion >= 7.0f) {

    // Move the view down 20 pixels
    CGRect bounds = self.view.bounds;
    bounds.origin.y -= 20.0;
    [self.navigationController.view setBounds:bounds];

    // Create a solid color background for the status bar
    CGRect statusFrame = CGRectMake(0.0, -20.0, bounds.size.width, 20);
    UIView* statusBar = [[UIView alloc] initWithFrame:statusFrame];
    statusBar.backgroundColor = [UIColor whiteColor];
    [statusBar setAlpha:1.0f];
    [statusBar setOpaque:YES];
    [self.navigationController.view addSubview:statusBar];
}

Elle est similaire à la solution de Hot Licks mais applique la sous-vue au navigationController.

sfr14
la source
C'est la seule réponse qui a fonctionné pour moi dans iOS 8!
SamB
0
override func viewDidLoad() {
 // your code

 if let nc = self.navigationController {
   yourView.frame.origin.y = nc.navigationBar.frame.origin.y + nc.navigationBar.frame.height
  }
}
wajih
la source
0

Voici un Swift 2.3. (Xcode 8.0). J'ai créé une sous-classe de UITableView.

class MYCustomTableView: UITableView
{   
    override func drawRect(rect: CGRect) {
        super.drawRect(rect)
        contentInset    = UIEdgeInsetsZero
    }
}

L'encart de contenu doit toujours être zéro (par défaut). Je le mets à zéro manuellement. Vous pouvez également ajouter une méthode de vérification qui effectue la vérification et si c'est autre chose que ce que vous voulez, obtenez simplement le bon rect. Le changement ne se reflétera que lorsque la vue de table est dessinée (ce qui n'arrive pas souvent).

N'oubliez pas de mettre à jour le TableView dans votre IB (dans le TableViewController ou tout simplement TableView dans votre ViewController).

Darkwonder
la source
0

J'étais confronté à ce problème dans ios 11 mais la mise en page était correcte pour ios 8 - 10.3.3. Pour mon cas, j'ai défini une contrainte d'espace vertical sur Superview.Top Margin au lieu de Superview.Top qui fonctionne pour ios 8-11.

entrez la description de l'image ici

DareDevil
la source
0

J'ai trouvé le moyen le plus simple de le faire, surtout si vous ajoutez votre vue de table à l'intérieur de la barre d'onglets, c'est d'abord d' ajouter une vue , puis d'ajouter la vue de table à l'intérieur de cette vue . Cela vous donne les meilleurs guides de marge que vous recherchez.

entrez la description de l'image ici

NSCoder
la source
-1

voir toutes les solutions: mon projet consiste simplement à utiliser xib, donc la solution avec storyboard n'a pas fonctionné pour moi. self.edgesForExtendedLayout = UIRectEdgeNone; fonctionne juste pour le contrôleur si la barre de navigation est visible. mais si votre vue est simplement dotée d'une barre d'état, cela ne fonctionnera pas. donc je combine deux conditions.

- (void) viewDidLayoutSubviews {
float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if (systemVersion >= 7.0f) {
    CGRect bounds = self.view.bounds;
    if(self.navigationController == nil || self.navigationController.isNavigationBarHidden == YES){
        bounds.origin.y -= 20.0;
        [self.view setBounds:bounds];
    }
    else{
        self.edgesForExtendedLayout = UIRectEdgeNone;
    }
}

aider cela fonctionne.

phnix
la source
-2

Si vous devez également prendre en charge iOS 6, vous devrez le déplacer de manière conditionnelle vers le bas. Autrement dit, dans iOS 7, vous devez simplement le déplacer vers le bas de 20 points (soit par framemanipulation ou en utilisant la mise en page automatique), et dans iOS 6, vous le laissez seul. Je ne crois pas que vous puissiez le faire dans IB, vous devrez donc le faire dans le code.

ÉDITER

Vous pouvez réellement le faire dans IB, en utilisant les deltas iOS6 / iOS7. Définissez votre position dans iOS 7, puis pour iOS 6, définissez le delta Y sur -20points. Voir cette question SO pour plus d'informations.

Scott Berrevoets
la source
Le réglage du cadre ne le change malheureusement pas.
Nicholas Smith
Qu'est-ce qui ne marche pas? La vue de table ne descend pas?
Scott Berrevoets
Oui, il reste dans la même position. J'ai essayé self.view.frameet self.tableView.frame, dans les deux viewWillAppearet viewDidLoad. Pour être en sécurité, j'ai également décidé setContentNeedsDisplayde forcer un nouveau dessin.
Nicholas Smith
La mise en page automatique est-elle activée?
Scott Berrevoets
Ouais, c'est autolayout et Storyboard.
Nicholas Smith