it-swarm.com.de

Inhalt wurde in einem UIPageViewController mit UINavigationController nach unten verschoben

UPDATE 2

Ich habe meine App im iOS-Simulator mit einem 4-Zoll-Gerät ausgeführt und getestet. Wenn ich mit einem 3,5-Zoll-Gerät laufe, springt das Etikett nicht. In meiner .xib, unter Simulated Metrics, habe ich es als Retina 4-Zoll-Vollbild eingestellt. Irgendeine Idee, warum ich dieses Problem nur auf einem 4-Zoll-Gerät sehe?

UPDATE 1

Wenn ich in IB in simulierten Metriken "Navigationsleiste" wähle, springt mein Label immer noch. Die einzige Möglichkeit, mein Etikett auf dem ersten Bildschirm korrekt rendern zu lassen, besteht darin, einen Navigationscontroller nicht als Root-View-Controller meines Fensters festzulegen.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Der rootViewController meines Fensters wird auf einen UINavigationController gesetzt, in dessen rootViewController ein UIPageViewController eingebettet ist.

Wenn meine App geladen wird, wird die erste Ansicht mit einem etwas nach unten gedrückten Inhalt angezeigt, der ungefähr der Größe einer Navigationsleiste entspricht. Wenn ich den pageViewController scrolle, springt der Inhalt dahin, wo er in der Spitze platziert wurde, und alle anderen viewController, die vom pageViewController geladen werden, sind in Ordnung.

uipageviewcontroller with navigationcontroller

In meiner appDelegate:

self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[ContainerViewController new]];

In 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];
}
59
djibouti33

Ich füge also nach der weiteren Entwicklung eine weitere Antwort hinzu und denke, ich habe herausgefunden, was los ist. UIPageViewController hat scheinbar unter iOS7 ein eigenes UIScrollView. Aus diesem Grund müssen Sie automaticallyAdjustsScrollViewInsets auf false setzen. Hier ist meine viewDidLoad jetzt:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.automaticallyAdjustsScrollViewInsets = false;

    DetailViewController *detail = [[DetailViewController alloc] init];
    [self setViewControllers:@[detail]
                   direction:UIPageViewControllerNavigationDirectionForward
                    animated:false
                  completion:nil];
}

Keine Notwendigkeit, etwas in viewWillLayoutSubviews zu setzen (wie eine meiner vorherigen Antworten vorgeschlagen wurde).

83
djibouti33

Dies wird definitiv von automaticallyAdjustsScrollViewInsets als anderen Postern (einschließlich @ djibouti33) verursacht. Diese Eigenschaft ist jedoch in zweierlei Hinsicht seltsam:

  1. Es muss auf eine UINavigationController gesetzt werden. Wenn Sie einen untergeordneten Controller festlegen, der von einer UINavigationController verwaltet wird, hat dies keine Auswirkungen. 1
  2. Dies gilt nur, wenn eine Bildlaufansicht in den Unteransichten eines Controllers den Index Null hat. 2

Diese beiden Einschränkungen sollten die intermittierenden Probleme erklären, die andere Benutzer im Thread haben.

TLDR: Eine Problemumgehung, mit der ich gearbeitet habe, ist das Hinzufügen einer Dummy-Ansicht zur UIPageViewController am Index 0, um zu vermeiden, dass die Einstellung für das scrollView innerhalb des Page-Controllers wie folgt gilt:

pageViewController.view.insertSubview(UIView(), atIndex: 0) // Swift

[pageViewController.view insertSubview: [UIView new] atIndex: 0]; // obj-c

Besser wäre es, die Variable contentInset in der Bildlaufansicht selbst festzulegen, aber leider zeigt die Variable UIPageViewController die Bildlaufansicht nicht an.

22
John Gibb

Deaktivieren Sie einfach Under Top Bars für beide: UIPageViewController und Ihre benutzerdefinierte PageContentViewController:

 enter image description here

Meine ursprüngliche Antwort löste das Problem vorerst, aber nach einer Weile kam das gleiche Problem zurück, um mich zu beißen.

Verwenden der folgenden viewController-Hierarchie:

-- UINavigationController
  -- MyPageViewController
    -- MyDetailViewController

So habe ich es gelöst:

In 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];
}
4
djibouti33

Deaktivieren Sie diese beiden Optionen in Ihrem Storyboard

 enter image description here

3
apinho

Ich habe das gleiche Problem. Ich löse es, indem ich setViewControllers für die erste Seite in viewDidLoad von UIPageViewController einsetze, anstatt es festzulegen, wenn ich eine Instanz von UIPageViewController erstelle. Ich muss außerdem automatischAdjustsScrollViewInsets auf NO setzen.

3
howa

Ich hatte ein ähnliches Problem, aber keine der Lösungen funktionierte hier. Mein Problem war, dass der Inhalt jedes Mal, wenn ich zur nächsten Seite blättere, nach unten springt und an der korrekten Position endet, aber 20 Pixel zu hoch beginnt (eindeutig etwas mit der Statusleiste zu tun). Mein Container VC war kein Nav VC. Nachdem ich mir eine Weile die Haare ausgezogen hatte, bestand die Lösung, die für mich gearbeitet hatte, darin, sicherzustellen, dass keine der Einschränkungen in meinem Inhalt VC mit der obersten Layout-Anleitung in Verbindung stand. Dies ist in Ihrem Fall vielleicht nicht machbar, aber in meinem Fall war es das einzige, was den Inhaltssprung gelöst hat. Sehr seltsamerweise trat dieses Problem nur dann auf, wenn der Übergangsstil auf Bildlauf eingestellt war. Durch das Umstellen auf Page Curl wurde das Problem verschwunden. Aber ich musste blättern. Hoffe das hilft jemand anderem.

3
Danny

Versuchen Sie, UIPageViewController im Storyboard auszuwählen, und deaktivieren Sie im Eigenschafteninspektor die Option "Unter unterste Leiste" und "Unter undurchsichtige Leiste".

1
acid beast

Keiner der oben genannten hat für mich gearbeitet 

Hier habe ich die Lösung gefunden

var pageMenu : CAPSPageMenu?

Anstatt so hinzuzufügen

self.view.addSubview(pageMenu!.view)

Fügen Sie Ihr CAPSPageMenu wie folgt hinzu

addChildViewController(pageMenu!) 
self.view.addSubview(pageMenu!.view) 
pageMenu!.didMove(toParentViewController: self)

Referenz: iOS Swift: SlidingMenuView falsche Position nach Präsentation von imagePicker

Viel Spaß beim Codieren!

0
Sanju

Wie von "Bo:" angegeben: self.edgesForExtendedLayout = UIRectEdgeNone setzen; in der viewDidLoad von MyPageViewController das Problem gelöst. - Bo

0
osxdirk

Ich sehe dasselbe Problem wie beschrieben von @Danny unter iOS 9. Ich habe versucht, alle Einschränkungen dahingehend zu aktualisieren, dass sie nicht an die Ränder gebunden sind, aber das Problem wurde nicht behoben die Angelegenheit. Ich musste am Ende einen Hack annehmen, der diesem wie folgt ähnelte;

  • Suchen Sie für jede Inhaltsseite, die im UIPageViewController angezeigt werden soll, die oberste Einschränkung, diejenige zwischen dem oberen Teil einer Ansicht und dem unteren Rand des oberen Layoutleitfadens, und fügen Sie dem Ansichtscontroller einen Auslass dafür hinzu.
  • Fügen Sie in jedem View-Controller mit einem solchen Auslass eine weitere Eigenschaft für die bevorzugte obere Entfernung hinzu. Die beiden Verkaufsstellen sehen so aus (in Swift):

    @IBOutlet weak var topGuideConstraint: NSLayoutConstraint!
    var topDistance: CGFloat!
    
  • Setzen Sie in viewDidLoad()topDistance auf den Wert, der der Einschränkung im Storyboard zugewiesen ist:

    override func viewDidLoad() {
        super.viewDidLoad()
        topDistance = topGuideConstraint.constant
    }
    
  • Stellen Sie in viewWillLayoutSubviews() sicher, dass die Einschränkung den richtigen Wert hat, und passen Sie die Höhe der Statusleiste an, wenn topLayoutGuide.length Null ist. Dies scheint der Fall während des Übergangs zu sein, jedoch nicht, sobald sie abgeschlossen ist: 

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        topGuideConstraint.constant = topDistance + (
            topLayoutGuide.length == 0
                ? UIApplication.sharedApplication().statusBarFrame.size.height
                : 0
        )
    }
    

Wiederholen Sie diesen Vorgang für jeden Content-View-Controller, der im UIPageViewController angezeigt wird. Passen Sie den Versatz entsprechend an, wenn Sie auch eine UINavigationsleiste anzeigen.

Dies ist ein unglücklicher Hacker, und ich hasse es, es tun zu müssen, aber nach vielen Stunden, die ich mit verschiedenen Dingen versucht habe, bin ich zumindest glücklich, etwas zu haben, das funktioniert, damit ich weitermachen kann.

0
theory

Swifts Version der Antwort von djibouti33 (mit Ausnahme der Zeile, die nicht zur Problemlösung gehört)

Swift 3.0

override func viewDidLoad() {
    super.viewDidLoad()
    self.automaticallyAdjustsScrollViewInsets = false
}
0
Kqtr

dies ist mein erster Beitrag zum Stack-Überlauf, aber ich suche seit über einer Woche nach einer Lösung für dieses Problem. 

Hier ist eine Lösung, die ich mir ausgedacht habe. Ich hoffe, das funktioniert für alle anderen mit dem gleichen Problem.

Ich bin nicht sicher, wie Sie Ihren Frame für Ihren Detailansicht-Controller initialisieren, aber ich gehe davon aus, dass Sie Folgendes verwenden könnten: self.view.frame.size.height;

versuchen Sie es mit: self.view.frame.size.height - = self.navigationController.navigationBar.bounds.size.height;

Hoffe das hilft

0
CalebDavis

As @ djibouti33 hat bereits gepostet: 

ein pageViewController konnte nicht Richten Sie den untergeordneten View-Controller zunächst richtig aus, wenn er eine .__ enthält. Scroll-Ansicht. Als wir in layoutSubviews sind, scheint pageViewController seine Orientierung gefunden zu haben und alles ist gut angelegt

Das Warten auf das Laden von layoutSubViews vor dem Setzen von viewControllers auf den UIPageViewController war das Einzige, was für mich funktionierte.

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

Anfangs sah meine View Controller-Hierarchie folgendermaßen aus:

-- UINavigationController
  -- MyContainerViewController
    -- UIPageViewController
      -- MyDetailViewController

Ich habe es so eingerichtet, damit MyContainerViewController eine Symbolleiste verwalten kann. Ich beschränkte mein Problem auf MyContainerViewController, und dann kam mir der Gedanke, dass ich es nicht einmal brauche, wenn ich UIPageViewController unterstütze. Nun sieht meine Hierarchie so aus:

-- UINavigationController
  -- MyPageViewController
    -- MyDetailViewController

MyPageViewController verwaltet seine toolbar und alles funktioniert wie erwartet, sowohl auf einem 4-Zoll- als auch einem 3,5-Zoll-Gerät.

0
djibouti33