Frage

So habe ich diese iPhone-App mit einer verschachtelten Setup wie folgt aus: [RootViewController] -> [UITabBarController] -> [UINavigationController] -> [subViewControllers]. Alles wird gebaut programmatisch, nicht in Interface Builder.

Ich versuche einfach alle Geräte Orientierungen zu unterstützen. Alle meine automatischen Größen Masken eingerichtet sind, und alles dreht und sich ausdehnt / Verträge wie nötig. Alles, außer für die Navigation des navBar und Toolbar. (In der Regel werden diese Ansichten Auto-Resize auf die Ausrichtung automatisch abhängig. Dh in Landschaft, die navbar und Symbolleiste automatisch über 32px und 44px in Portrai Modus Größe ändern sollte.) Was eigenartig ist, dass der Subview des Navigations Controller Ändern der Größe, aber die tatsächliche navBar und Symbolleiste nicht. Mit anderen Worten, die Inhalt Strecken / schrumpft etwa 12 Pixel oder so in welcher Richtung auch immer, als ob die Navigationsleiste und die Symbolleiste angepasst. Dies scheint die automatischen Größen Masken ihre Arbeit tun zu können.

Also, um diese Situation zu lösen, um zu versuchen, habe ich eine Kategorie für UINavigationController, dass reagiert auf ‚willRotateToInterfaceOrientation: Dauer:‘ um die ‚sizeToFit‘ Wähler auszulösen. (Diese Technik kam aus einem anderen Beitrag auf Stack-Überlauf, mit einem ähnlichen Problem.) Entdeckte ich, in meiner Forschung, dass nur die äußerste View-Controller diese Nachricht empfängt, jedoch, so dass ich mein Root-View-Controller haben diese Controller auf der Registerkarte aufrufen, die wiederum ruft sie auf dem nav-Controller, etc. Dies dieses Problem kümmerten, und jetzt meine verschachtelten view-Controller gemeldet werden, wenn die äußere Ansicht gedreht wird. Mit Hilfe der sizeToFit Technik, sowohl die Navigationsleiste und die Symbolleiste resizen auf eigene Faust. Allerdings läßt, dass nach wie vor das Problem der Symbolleiste Neupositionierung, um für den Versatz von der Größenänderung zu bilden. (Da unsere Ansicht Koordinaten in iPhone links oben beginnen.)

Was diese heikel macht im willRotate Methode zu tun ist, dass wir nicht wissen, was die neuen Begrenzungs Ansicht Dimensionen sein, wir wissen auch nicht, was unsere aktuelle Ausrichtung ist. (Es sei denn, Sie deviceOrientationNotifications eingeschaltet haben, die ich nicht tun.) Alles, was wir Arbeit haben mit dem, was die neue Ausrichtung sein wird, und was aktuellen Frame Werte unseres Symbolleiste sind. Ich konnte hart Code dieses und berechnen Rahmen Anpassungen auf die altmodische Art und Weise ein Stück Schmierpapier verwendet wird, aber ich möchte die dynamische Ansicht Sizing Merkmale beibehalten, ohne irgendwelche Annahmen über die Bildschirmabmessungen des Geräts.

Deshalb den folgenden Code verwendet, gelang es mir, hier Abhilfe zu schaffen, indem einfach ‚Stoßen‘ die Symbolleiste von 12px im Verhältnis zur Größe es gerade wurde. Um es von über Anstoßen zu verhindern, wenn der Benutzer das Gerät dreht, verwende ich die Rahmenhöhe der aktuellen-Symbolleiste die aktuelle Ausrichtung abzuleiten. (Das bedeutet, ich bin immer noch macht eine Annahme über die Symbolleiste vor und nach Größen, aber ich fühle mich besser über, da ich, dass zu einem gewissen Grad zu versuchen, das Gerät des physischen Bildschirm programmatisch zu ändern. Im Gegensatz zu beeinflussen)

@implementation UINavigationController (BLUINavigationControllerAutoRotate)

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    return TRUE;
}

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];

    // Resize the navBar
    [[self navigationBar] performSelector:@selector(sizeToFit)
                               withObject:nil
                               afterDelay:(0.5f * duration)];

    // Read our current frame size
    CGRect toolbarFrame = self.toolbar.frame;

    // Prevent over adjusting when flipping the device
    if ((toolbarFrame.size.height < 38
         && (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft
             || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight))
        || (toolbarFrame.size.height > 38
            && (toInterfaceOrientation == UIInterfaceOrientationPortrait
                || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)))
    {
        // We are already resized and repositioned.
        return;
    }

    // Calculate and apply the toolbar offset
    const NSInteger delta = 12;     // the difference in size between 44 and 32 px.
    toolbarFrame.origin.y += ((toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft)
                              || (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)) ? (delta) : (-delta);
    self.toolbar.frame = toolbarFrame;

    // Resize the toolbar
    [[self toolbar] performSelector:@selector(sizeToFit)
                         withObject:nil
                         afterDelay:(0.5f * duration)];

}

@end

So, jetzt habe ich benommen richtig navigationbar und Toolbar. Der Endbenutzer wird nie wissen, dass ich all diese zusätzlichen Arbeit-um, um zu implementieren, wieder zu aktivieren, was wie angenommen wird, scheint ein Standard-Verhalten sein. Also meine Frage ist, warum muss ich all dies tun? Gibt es einen besseren Ansatz, den ich wissen soll, oder etwas, dass ich einfach nicht an anderer Stelle tue? (Dh [Navigation setAutomaticallyResizesToolbarOnRotate: TRUE];? Oder so ähnlich) Wie ich schon sagte, dies scheint wie es angenommen hat, wird vorverdrahtet, so für mich, mit Weiterleitung von Nachrichten und gezwungen Trigger sind wie ein over-engineered Hack müssen finagle anstatt die richtige Lösung.

Danke!

War es hilfreich?

Lösung

Sie vorbei an der willRotateToInterfaceOrientation Nachricht auf die Registerkarte View-Controller von Ihrem Root-View-Controller - warum passieren nicht alle auf die andere Dreh Nachrichten und sehen, ob das hilft? d.

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
    [tabBarController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
}

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
    [tabBarController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation  {
    [super didRotateFromInterfaceOrientation:toInterfaceOrientation];
    [tabBarController didRotateFromInterfaceOrientation:toInterfaceOrientation];
}

- (void)willAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
    [tabBarController willAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
}

- (void)didAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    [super didAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation];
    [tabBarController didAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation];
}

- (void)willAnimateSecondHalfOfRotationFromInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willAnimateSecondHalfOfRotationFromInterfaceOrientation:toInterfaceOrientation duration:duration];
    [tabBarController willAnimateSecondHalfOfRotationFromInterfaceOrientation:toInterfaceOrientation duration:duration];
}

ich interessiert wäre, um zu sehen, was passiert, wenn Sie alle diese Tab-Leiste Controller passieren - Ihr Problem scheint wie etwas, das automatisch geschehen soll, statt die ganze zusätzliche Arbeit, die du getan hast

!
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top