UITabbar Animation- „Artefakte”

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • UITabbar Animation- „Artefakte”

    Hallöchen– ich mal wieder.

    Und wieder ein Problem mit einer Animation. Ich habe mir nämlich gedacht, ich baue eine schöne Transition für den Wechsel der VIewController über eine Tabbar.
    Und zwar habe ich dafür den UITabBarViewController abgeleitet. Meine Animation 'schiebt' die Views der ViewController nach links/rechts, je nach dem, wo der Zieltab ist.
    Das ist auch recht hübsch, allerdings kommt man da zu einem Problem, wenn man von einem UINavigationController zu einem nicht-UINavigationController wechselt bzw. umgekehrt.
    Dann nämlich sind die neuen Views jeweils um die Höhe der Statusbar verschoben. Wenn ich das ausgleiche, bleibt unten- direkt über der Tabbar- ein schwarzes Rechteck während der Animation sichtbar.

    Der Animationscode:

    Quellcode

    1. - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
    2. {
    3. int controllerIndex = [[tabBarController viewControllers] indexOfObject:viewController];
    4. if(controllerIndex == self.selectedIndex || self.isAnimating)
    5. {
    6. return NO;
    7. }
    8. UIView *fromView = tabBarController.selectedViewController.view;
    9. UIView *toView = [viewController view];
    10. CGRect viewSize = fromView.frame;
    11. BOOL scrollRight = controllerIndex > tabBarController.selectedIndex;
    12. [fromView.superview addSubview:toView];
    13. if ([self shouldAdjustFrameDownFromViewController:tabBarController.selectedViewController toViewController:viewController])
    14. {
    15. toView.frame = CGRectMake((scrollRight ? 320 : -320), viewSize.origin.y+20, 320, viewSize.size.height);
    16. }
    17. else if ([self shouldAdjustFrameUpFromViewController:tabBarController.selectedViewController toViewController:viewController])
    18. {
    19. toView.frame = CGRectMake((scrollRight ? 320 : -320), viewSize.origin.y-20, 320, viewSize.size.height);
    20. }
    21. else
    22. {
    23. toView.frame = CGRectMake((scrollRight ? 320 : -320), viewSize.origin.y, 320, viewSize.size.height);
    24. }
    25. [toView setNeedsDisplay];
    26. [UIView animateWithDuration:0.3 animations: ^
    27. {
    28. [self.tabBar setUserInteractionEnabled:NO];
    29. toView.alpha = 0;
    30. fromView.frame = CGRectMake((scrollRight ? -320 : 320), viewSize.origin.y, 320, viewSize.size.height);
    31. if ([self shouldAdjustFrameDownFromViewController:tabBarController.selectedViewController toViewController:viewController])
    32. {
    33. toView.frame = CGRectMake(0, viewSize.origin.y+20, 320, viewSize.size.height);
    34. }
    35. else if ([self shouldAdjustFrameUpFromViewController:tabBarController.selectedViewController toViewController:viewController])
    36. {
    37. toView.frame = CGRectMake(0, viewSize.origin.y-20, 320, viewSize.size.height);
    38. }
    39. else
    40. {
    41. toView.frame = CGRectMake(0, viewSize.origin.y, 320, viewSize.size.height);
    42. }
    43. [UIView animateWithDuration:0.8 animations:^
    44. {
    45. [fromView setAlpha:0];
    46. [toView setAlpha:1];
    47. }
    48. completion:^(BOOL finished)
    49. {
    50. [fromView setAlpha:1];
    51. }];
    52. }
    53. completion:^(BOOL finished)
    54. {
    55. if (finished)
    56. {
    57. [toView setNeedsDisplay];
    58. [fromView removeFromSuperview];
    59. tabBarController.selectedIndex = controllerIndex;
    60. [self.tabBar setUserInteractionEnabled:YES];
    61. }
    62. }];
    63. return NO;
    64. }
    Alles anzeigen


    Es ist eben sehr unschön, ich habe diesen Verschub eben ausgeglichen und dann hat man an andere Stelle ein Problem. Die Animation gefällt mir aber so gut…
    Ich hänge Euch mal das Beispielprojekt an. Vielleicht findet ja von Euch jemand einen Fehler in meinem Animationscode bzw. im Setup meines Codes.

    Mein Ziel wäre es eben, dass die Übergänge zwischen UINavigationControllern zu non-UINavigationControllern sauber läuft.
  • Eine should*-Methode für sowas zu verwenden, ist eine schlechte Idee. Diese Methode sollte nur mit YES oder NO antworten. Zu etwas anderem ist sie nicht gedacht. Außerdem solltest Du mit relativen Koordinaten und nicht mit absoluten arbeiten. Ein fester Wert für die Höhe der Statusleiste ist auch nicht optimal. Hier solltest Du lieber mit bounds arbeiten.

    Ich habe es mal mit Überschreiben von setSelectedViewController: ausprobiert:

    Quellcode

    1. - (void)setSelectedViewController:(UIViewController *)inViewController {
    2. CGRect theFrame = self.view.bounds;
    3. [super setSelectedViewController:inViewController];
    4. inViewController.view.frame = CGRectOffset(theFrame, CGRectGetWidth(theFrame), 0.0);
    5. [UIView animateWithDuration:0.75
    6. animations:^{
    7. inViewController.view.frame = theFrame;
    8. }
    9. completion:^(BOOL inFinished) {
    10. }];
    11. }
    Alles anzeigen

    Während sich das erste Hereinschieben damit noch ganz gut funktioniert, klappt es bei den späteren Wechseln nicht mehr. Auch das Herausschieben ist schwierig. Eine Transition anstelle einer Animation brachte auch mehr Probleme als Vorteile.

    Fazit: Ich würde einen eigenen Container-Viewcontroller schreiben, der wie ein Tabbar-Controller funktioniert. Da kannst Du die Animationen selber festlegen.
    „Meine Komplikation hatte eine Komplikation.“