MISE À JOUR 2
J'ai exécuté et testé mon application dans le simulateur iOS à l'aide d'un périphérique de 4 pouces. Si j'utilise un périphérique 3,5 pouces, l'étiquette ne saute pas. Dans mon fichier .xib, sous Méthodes simulées, je l’ai défini comme Retina 4 pouces plein écran. Une idée de pourquoi je ne vois ce problème que sur un appareil de 4 pouces?
MISE À JOUR 1
Dans IB, si je choisis "Barre de navigation" dans Métriques simulées, mon étiquette saute toujours. Le seul moyen d'obtenir un rendu correct de l'étiquette sur le premier écran est de ne pas définir de contrôleur de navigation comme contrôleur de vue racine de ma fenêtre.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RootViewController de ma fenêtre est défini sur un UINavigationController dont rootViewController est doté d'un UIPageViewController.
Lorsque mon application est chargée, la vue initiale est présentée avec son contenu légèrement abaissé, à peu près de la même taille qu'une barre de navigation. Lorsque je fais défiler le pageViewController, le contenu saute à l'endroit où il a été placé dans le nib, et tous les autres viewControllers chargés par le pageViewController conviennent.
Dans mon appDélégant:
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[ContainerViewController new]];
Dans ContainerViewController:
- (void)viewDidLoad {
[super viewDidLoad];
self.pvc = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll
navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal
options:nil];
self.pvc.dataSource = self;
self.pvc.delegate = self;
DetailViewController *detail = [DetailViewController new];
[self.pvc setViewControllers:@[detail]
direction:UIPageViewControllerNavigationDirectionForward
animated:false
completion:nil];
[self addChildViewController:self.pvc];
[self.view addSubview:self.pvc.view];
[self.pvc didMoveToParentViewController:self];
}
J'ajoute donc une autre réponse après un développement ultérieur et je pense enfin avoir compris ce qui se passait. On dirait que dans iOS7, UIPageViewController a son propre UIScrollView. Pour cette raison, vous devez définir automaticallyAdjustsScrollViewInsets
sur false. Voici ma viewDidLoad
maintenant:
- (void)viewDidLoad
{
[super viewDidLoad];
self.automaticallyAdjustsScrollViewInsets = false;
DetailViewController *detail = [[DetailViewController alloc] init];
[self setViewControllers:@[detail]
direction:UIPageViewControllerNavigationDirectionForward
animated:false
completion:nil];
}
Pas besoin de mettre quoi que ce soit dans viewWillLayoutSubviews
(comme l’a suggéré une de mes réponses précédentes).
Ceci est certainement causé par automaticallyAdjustsScrollViewInsets
, comme d’autres affiches (y compris @ djibouti33). Cependant, cette propriété est étrange de deux manières:
UINavigationController
. Si vous le définissez sur un contrôleur enfant géré par une UINavigationController
, cela n'aura aucun effet. 1Ces deux mises en garde devraient expliquer les problèmes intermittents rencontrés par d’autres personnes du fil.
TLDR: Une solution de contournement que j'ai choisie consiste à ajouter une vue factice à la variable UIPageViewController
d'indice zéro afin d'éviter que le paramètre ne s'applique à scrollView dans le contrôleur de page, comme suit:
pageViewController.view.insertSubview(UIView(), atIndex: 0) // Swift
[pageViewController.view insertSubview: [UIView new] atIndex: 0]; // obj-c
Il serait préférable de définir vous-même la contentInset
sur la vue de défilement, mais malheureusement, la UIPageViewController
n'expose pas la vue de défilement.
Ma réponse initiale résolut le problème pour le moment, mais après un moment, le même problème revint me mordre.
Utilisation de la hiérarchie viewController suivante:
-- UINavigationController
-- MyPageViewController
-- MyDetailViewController
Voici ce que j'ai fait pour le résoudre:
Dans MyPageViewController.m
@interface MyPageViewController () <delegates>
@property (strong) MyDetailViewController *initialViewController;
@end
- (void)viewDidLoad
{
...
// set this once, because we're going to use it in viewWillLayoutSubviews,
// which gets called multiple times
self.initialViewController = [MyDetailViewController new];
}
// the problem seemed to stem from the fact that a pageViewController couldn't
// properly lay out it's child view controller initially if it contained a
// scroll view. by the time we're in layoutSubviews, pageViewController seems to
// have gotten it's bearings and everything is laid out just fine.
- (void)viewWillLayoutSubviews
{
[self setViewControllers:@[self.initialViewController]
direction:UIPageViewControllerNavigationDirectionForward
animated:false
completion:nil];
}
J'ai le même problème. Je le résous en mettant setViewControllers pour la première page dans viewDidLoad de UIPageViewController au lieu de le définir lorsque je crée une instance de UIPageViewController. En outre, je dois définir automatiquementAdjustsScrollViewInsets sur NO.
J'ai eu un problème similaire, mais aucune des solutions ici n'a fonctionné. Mon problème était que chaque fois que je passais à la page suivante, le contenu sautait vers le bas, se terminant à la bonne position, mais commençant à 20 pixels de trop, ce qui est clairement lié à la barre d'état. Mon conteneur VC n'était pas un VC de navigation. Après m'être tiré les cheveux pendant un moment, la solution qui a finalement fonctionné pour moi consistait simplement à m'assurer qu'aucune des contraintes de mon contenu VC n'était connectée au guide de présentation supérieur. Cela peut ou peut ne pas être réalisable dans votre cas, mais dans le mien c'était, et c'était la seule chose qui a résolu le saut de contenu. Aussi très curieusement, ce problème ne s'est manifesté que lorsque le style de transition a été défini pour défiler. Le simple fait de changer de page en boucle a fait disparaître le problème. Mais j'avais besoin de faire défiler. J'espère que ceci aide quelqu'un d'autre.
Essayez de sélectionner UIPageViewController dans le storyboard et décochez les cases "Sous les barres inférieures" et "Sous les barres opaques" dans l'Inspecteur des attributs.
Aucun de ceux ci-dessus n'a fonctionné pour moi
Ici j'ai trouvé la solution
var pageMenu : CAPSPageMenu?
Au lieu d'ajouter comme ça
self.view.addSubview(pageMenu!.view)
Ajoutez votre CAPSPageMenu comme ci-dessous
addChildViewController(pageMenu!)
self.view.addSubview(pageMenu!.view)
pageMenu!.didMove(toParentViewController: self)
Référence: iOS Swift: SlidingMenuView Position incorrecte après avoir présenté imagePicker
Bon codage!
Comme indiqué par "Bo:": Putting self.edgesForExtendedLayout = UIRectEdgeNone; dans le viewDidLoad de MyPageViewController a résolu le problème. - Bo
Je vois le même problème que décrit par @Danny sur iOS 9. J'ai essayé de mettre à jour toutes mes contraintes pour qu'elles ne soient pas contraintes aux marges , mais cela n'a pas résolu le problème. J'ai fini par adopter un hack similaire à this comme suit;
Dans chaque contrôleur de vue doté d'une telle prise, ajoutez une autre propriété pour la distance maximale préférée. Les deux sorties ressemblent à ceci (en Swift):
@IBOutlet weak var topGuideConstraint: NSLayoutConstraint!
var topDistance: CGFloat!
Dans viewDidLoad()
, définissez topDistance
sur la valeur attribuée à la contrainte dans le storyboard:
override func viewDidLoad() {
super.viewDidLoad()
topDistance = topGuideConstraint.constant
}
Dans viewWillLayoutSubviews()
, assurez-vous que la contrainte a la valeur appropriée, en ajustant la hauteur de la barre d'état lorsque le topLayoutGuide.length
est égal à zéro, ce qui semble être le cas lors de la transition , mais pas une fois terminée:
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
topGuideConstraint.constant = topDistance + (
topLayoutGuide.length == 0
? UIApplication.sharedApplication().statusBarFrame.size.height
: 0
)
}
Répétez cette opération pour chaque contrôleur d'affichage de contenu affiché dans UIPageViewController. Ajustez le décalage comme il convient si vous affichez également une barre UINavigation.
C'est un bidon malheureux, et je déteste devoir le faire, mais après de nombreuses heures à essayer différentes choses, je suis au moins heureux d'avoir quelque chose qui fonctionne pour que je puisse passer à autre chose.
La version de Swift de la réponse de djibouti33 (à l'exclusion de la ligne qui ne fait pas partie de la résolution du problème)
Swift 3.0
override func viewDidLoad() {
super.viewDidLoad()
self.automaticallyAdjustsScrollViewInsets = false
}
c'est la première fois que j'écris sur le débordement de pile, mais je cherche une solution à ce problème depuis plus d'une semaine maintenant.
Voici une solution que j'ai proposée, j'espère que cela fonctionnera pour tous ceux qui ont le même problème.
Je ne sais pas comment vous initialisez votre cadre pour votre contrôleur de vue de détail, mais je vais supposer que vous pourriez utiliser: self.view.frame.size.height;
essayez d’utiliser: self.view.frame.size.height - = self.navigationController.navigationBar.bounds.size.height;
J'espère que cela t'aides
Comme @ djibouti33 déjà posté:
un pageViewController ne pouvait pas disposer correctement son contrôleur de vue enfant au début s'il contenait un voir défiler. au moment où nous sommes dans layoutSubviews, pageViewController semble avoir pris ses marques et tout est très bien présenté
Attendre le chargement de layoutSubViews avant de définir des viewControllers sur UIPageViewController était la seule chose qui fonctionnait pour moi.
override func viewDidLoad() {
super.viewDidLoad()
self.pageViewController = self.storyboard?.instantiateViewController(withIdentifier: "yourPageViewController") as? UIPageViewController
self.pageViewController?.dataSource = self
pageViewController?.automaticallyAdjustsScrollViewInsets = false
self.pageViewController?.view.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.height)
self.addChildViewController(self.pageViewController!)
self.view.addSubview((self.pageViewController?.view)!)
self.pageViewController?.didMove(toParentViewController: self)
}
override func viewDidLayoutSubviews() {
let startVC = self.viewControllerAtIndex(index: 0) as infoDataViewController
let viewControllers = NSArray(object: startVC)
self.pageViewController?.setViewControllers(viewControllers as? [UIViewController], direction: .forward, animated: true, completion: nil)
}
Au début, ma hiérarchie de contrôleur de vue ressemblait à ceci:
-- UINavigationController
-- MyContainerViewController
-- UIPageViewController
-- MyDetailViewController
Je l'ai configuré de cette manière pour que MyContainerViewController puisse gérer une barre d'outils. J'ai limité mon problème à MyContainerViewController, puis je me suis dit que je n'en ai même pas besoin si je sous-classe UIPageViewController. Maintenant, ma hiérarchie ressemble à ceci:
-- UINavigationController
-- MyPageViewController
-- MyDetailViewController
MyPageViewController
gère sa toolbar
et tout fonctionne comme prévu, aussi bien sur un périphérique 4 pouces que sur un périphérique 3,5 pouces.