web-dev-qa-db-fra.com

UIView ne se redimensionne pas en plein écran lorsque vous masquez la barre de navigation et la barre d'onglets

J'ai une application qui a une barre d'onglets et une barre de navigation pour une interaction normale. Un de mes écrans est une grande partie du texte, donc j'autorise l'utilisateur à taper pour passer en plein écran (un peu comme Photos.app).

La barre de navigation et la barre d'onglets sont masquées et j'ai défini le cadre de la vue texte en plein écran. Le problème est qu'il y a environ 50 pixels d'espace blanc où se trouvait la barre d'onglets. Vous pouvez voir si à partir de cette capture d'écran:

lien ImageShack mort supprimé

Je ne sais pas ce qui cause ça. L'espace blanc n'est certainement pas la vue derrière la vue texte, car j'ai défini sa couleur d'arrière-plan sur rouge juste pour être sûr. Qu'est-ce qui peut causer cela?

** METTRE À JOUR **

J'ai fait des tests de hit dans une sous-classe UIWindow et j'ai découvert que l'espace blanc est en fait le UILayoutContainerView non documenté/non publié. Il s'agit de la vue parent de la tabBar. Je ne pense pas qu'il soit recommandé de manipuler directement cette vue, alors comment masquer la barre d'onglets?

** MISE À JOUR # 2 **

J'ai vérifié l'image avant et après l'animation de self.view, et il semble que la vue parent ne soit pas suffisamment redimensionnée.

après être passé en plein écran, le cadre de la vue ne mesure que 411 pixels. J'ai essayé de jouer avec le cadre manuellement et de définir également autoResizeMask sans chance.

**** MISE À JOUR: Voici le résultat final ****

- (void)toggleFullscreen {
    isFullScreen = !isFullScreen;  //ivar

    //hide status bar & navigation bar
    [[UIApplication sharedApplication] setStatusBarHidden:isFullScreen animated:YES];
    [self.navigationController setNavigationBarHidden:isFullScreen animated:YES];

    [UIView beginAnimations:@"fullscreen" context:nil];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:.3];

    //move tab bar up/down
    CGRect tabBarFrame = self.tabBarController.tabBar.frame;
    int tabBarHeight = tabBarFrame.size.height;
    int offset = isFullScreen ? tabBarHeight : -1 * tabBarHeight;
    int tabBarY = tabBarFrame.Origin.y + offset;
    tabBarFrame.Origin.y = tabBarY;
    self.tabBarController.tabBar.frame = tabBarFrame;

    //fade it in/out
    self.tabBarController.tabBar.alpha = isFullScreen ? 0 : 1;

    //resize webview to be full screen / normal
    [webView removeFromSuperview];
    if(isFullScreen) {
                //previousTabBarView is an ivar to hang on to the original view...
        previousTabBarView = self.tabBarController.view;
        [self.tabBarController.view addSubview:webView];

        webView.frame = [self getOrientationRect];  //checks orientation to provide the correct rect

    } else {
        [self.view addSubview:webView];
        self.tabBarController.view = previousTabBarView;
    }

    [UIView commitAnimations];
}

(notez que j'ai basculé textview sur webview, mais la même chose fonctionne pour la vue texte d'origine)

37
Ben Scheirman

J'ai eu ce problème exact où j'animais la barre d'onglets et la barre de navigation respectivement en bas et en haut de l'écran, laissant un espace blanc élevé de 49 pixels où se trouvait la barre d'onglets.

Il s'avère que la raison pour laquelle ma nouvelle vue "plein écran" ne remplissait pas réellement l'espace était parce que j'ajoutais la vue plein écran en tant que sous-vue de la vue du contrôleur de navigation, qui était elle-même un enfant du contrôleur de la barre d'onglets.

Pour y remédier, j'ai simplement ajouté la nouvelle vue plein écran (dans votre cas, la vue avec tout le texte) en tant que sous-vue de la vue UITabBarController.

 [[[self tabBarController] view] addSubview: yourTextView]; 

Ensuite, tout ce que vous devez faire est de vous assurer que le cadre de votre sous-vue est de 480 x 320 pixels et qu'il devrait remplir l'écran (y compris la zone qui était auparavant le mystérieux espace blanc)

29
Harry

Vous pouvez certainement faire quelque chose qui semble correct en décalant le cadre de la vue de sorte que la barre d'onglets soit hors écran. Je sais que quelqu'un d'autre a mentionné avoir essayé cela, et vous avez dit que cela ne fonctionnait pas, mais je soupçonne que le problème est que vous n'avez pas configuré correctement le masque de redimensionnement des vues de texte lorsque vous avez essayé. Voici le code qui devrait fonctionner:

- (void)viewDidLoad {
  [super viewDidLoad];
  currentlyHidden = NO;
}

- (void) hideStuff {
  SO2AppDelegate *appDelegate = (id)[[UIApplication sharedApplication] delegate];
  self.navigationController.navigationBarHidden = YES;

  CGRect newFrame = appDelegate.tabBarController.view.frame;
  newFrame.size.height += appDelegate.tabBarController.tabBar.frame.size.height;
  appDelegate.tabBarController.view.frame = newFrame;
}

- (void) showStuff {
  SO2AppDelegate *appDelegate = (id)[[UIApplication sharedApplication] delegate];

  CGRect newFrame = appDelegate.tabBarController.view.frame;
  newFrame.size.height -= appDelegate.tabBarController.tabBar.frame.size.height;
  appDelegate.tabBarController.view.frame = newFrame;

  self.navigationController.navigationBarHidden = NO;
}

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {  
  if (currentlyHidden) {
    [self showStuff];
    currentlyHidden = NO;
  } else {
    [self hideStuff];
    currentlyHidden = YES;
  }
}

De plus, étant donné que cela est certainement sensible à la façon dont vous avez configuré vos plumes, etc., je suis publication un projet en ligne afin que vous puissiez le télécharger et le consulter. Il s'agit d'une démo assez minimale, juste un projet basé sur la navigation où le délégué configure un contrôleur d'onglets et intègre le contrôleur de vue à partir de la plume principale. Le reste se trouve dans la nib et la classe RootViewController. Les barres sont basculées chaque fois qu'une touche commence, il suffit donc de toucher l'écran. De toute évidence, dans une vraie application, vous devrez peut-être ajuster la vue de défilement pour que le contenu ne semble pas sauter.

5
Louis Gerbarg

Avez-vous défini la propriété hidesBottomBarWhenPushed de votre contrôleur de vue sur YES? Vous devez définir cela dans votre initWithNibName:bundle: ou initWithCoder: méthode. Lorsqu'il est poussé vers le contrôleur de navigation, cela devrait masquer la barre d'onglets et étendre la vue du contenu vers le bas.

3
Daniel Dickison

J'ai eu un problème similaire. Comme Harry l'a mentionné, c'est une raison pour laquelle le contrôleur de navigation est le contrôleur interne du contrôleur de barre d'onglets. Trouvé une autre façon de redessiner votre vue et d'avoir un cadre correct., Dans votre contrôleur, ajoutez ce qui suit:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    // Here you can make your tabBarControlelr.view.hidde = true or use any animation that hides UITabBar. I made
    [TabBarController setTabBarHidden:YES];

    self.navigationController.view.frame = CGRectMake(self.navigationController.view.frame.Origin.x, self.navigationController.view.frame.Origin.y, self.navigationController.view.frame.size.width, self.navigationController.view.frame.size.height + 50);
    [self.navigationController.view setNeedsLayout];

 }

Et voici comment je le cache. Je peux le faire appeler directement la méthode de TabBarControlelr ou le wrapper de méthode de classe:

+ (void)setTabBarHidden:(BOOL)hidden
{
    AppDelegate *delegate = [UIApplication sharedApplication].delegate;
    TabBarController *tabBarController = (TabBarController *) delegate.window.rootViewController;

    if ([tabBarController isKindOfClass:[TabBarController class]]) {
        [tabBarController setTabBarHidden:hidden];
    }
}


- (void)setTabBarHidden:(BOOL)hidden
{
    if (self.tabBar.hidden == hidden) {
        return;
    }

    if (hidden == NO) {
        self.tabBar.hidden = hidden;
    }

    [UIView animateWithDuration:0.15 animations:^{
        self.tabBar.frame = CGRectOffset(self.tabBar.frame, 0, ( hidden ? 50 : -50 ));
    } completion:^(BOOL finished) {
        self.tabBar.hidden = hidden;
    }];
}
2
anatoliy_v

J'ai constaté que si vous marquez la nouvelle vue, vous pousserez sur la pile de navigation avec la ligne suivante masque la barre d'onglets tant qu'elle est sur la pile.

scrollViewController.hidesBottomBarWhenPushed = YES;

2
Steve

Peut-être y a-t-il une autre vue qui fait partie intégrante de la zone de la barre d'onglets? C'est-à-dire quelque chose de plus à cacher. Cela vous aidera à voir quelles vues existent.

for (UIView *viewy in [self.navigationController.view subviews])
{
    NSLog([viewy description]);
}
2
ojreadmore

Je déplacerais la vue vers la fenêtre lorsque vous choisiriez de passer en plein écran. par exemple.

myView = [self.view retain];
self.view = nil;
[window addSubview:myView];

et pour revenir:

[myView removeFromSuperView];
self.view = myView;
[myView release];
myView = nil;

En ajoutant la vue en tant qu'enfant de la fenêtre, elle peut être totalement en plein écran et sera en haut de la barre d'onglets.

Vous pouvez ensuite combiner cela avec

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didRotate:) name:@"UIDeviceOrientationDidChangeNotification" object:nil];

pour détecter la rotation. (Je pense que vous combinez cela avec view.transform = CGAffineTransformMakeRotation pour le faire tourner ...?)

1
Benjie

Je crois que le problème est que vous êtes toujours dans le contrôleur de barre d'onglets, j'ai également rencontré quelques problèmes avec cela, et j'ai fini par créer deux vues pour mon délégué d'application à contrôler, le contrôleur de barre d'onglets et une vue séparée qui contient tout ce que le contrôleur de la barre d'onglets essaie de prendre en main. Vous pourriez transmettre votre point de vue au délégué de l'application et l'utiliser peut-être là-bas?

1
James Hall

Avez-vous tenté de forcer le texte à se "réécrire" lui-même (réinitialisation de la propriété .text de l'objet que vous utilisez)? J'ai eu de nombreux cas où les vues ne revérifient tout simplement pas ou ne repeignent pas leurs données, et le forçage semble être la seule solution. Si ce n'est pas bon du point de vue de l'expérience utilisateur, vous pouvez essayer de rendre les nav/tabbars transparents après que l'utilisateur touche, et avant qu'ils ne disparaissent. Cela étend normalement la vue à toute la taille de l'écran.

0
TahoeWolverine

Si vous utilisez Interface Builder, assurez-vous que le redimensionnement automatique est correctement défini dans l'inspecteur de taille. Si vous créez l'UITextView dans le code, assurez-vous que le cadre est suffisamment grand et que le parent de la vue (et son parent) est également suffisamment grand. Pour plus de simplicité, ajoutez directement la vue à la fenêtre, puis déplacez-vous vers l'intérieur à partir de là.

Pour déplacer une vue vers sa vue d'ensemble:

- (void)moveViewToSuperview:(UIView *)view
{
    UIView *newSuperview = [[view superview] superview];
    [view removeFromSuperview];
    [newSuperview addSubview:view];
    [newSuperview bringSubviewToFront:view];
}
0
rpetrich

Mettez le code dans une préparation pour une séquence comme celle-ci, fonctionne parfaitement pour moi:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"ViewPhoto"]) {

    ImageView *vc = [segue destinationViewController];

    NSInteger selectedIndex = [[self.tableView indexPathForSelectedRow] row];

        NSString *Title = [photoNames objectAtIndex:selectedIndex];
        [vc setSelectedTitle:[NSString stringWithFormat:@"%@", Title]];

        vc.hidesBottomBarWhenPushed = YES;

        }
    }
0
Deco

Si l'UITabBarController est poussé par un rootViewController (navigationController). Vous pouvez essayer ce qui suit:

Masquez d'abord la barre d'état/la barre d'onglets;

[self.navigationController pushViewController:aBlankViewController animated:NO];
[self.navigationController popViewControllerAnimated:NO];

Vous devriez pouvoir récupérer l'espace blanc, bien que l'écran choque pendant le réglage ...

0
xingzhi.sg

J'ai rencontré un problème similaire, cette discussion a été utile: IWebView sur iPad

Tony la réponse m'a aidé à découvrir que lorsque vous créez une sous-vue, il est utile de configurer un code similaire à ceci:

self.tabBarController.tabBar.frame = self.view.bounds;
0
Matt