5

I am trying to implement some custom transitions on the iPad but I am getting some issues. Since the x, y coordinates do not always start on the upper left corner in the containerView of the transitionContext when the device is rotated I wrote the following methods

- (CGRect)rectForPresentedStateStart:(id<UIViewControllerContextTransitioning>)transitionContext
{
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIView *containerView = [transitionContext containerView];
    
    switch (fromViewController.interfaceOrientation)
    {
        case UIInterfaceOrientationLandscapeRight:
            return CGRectMake(0, containerView.bounds.size.height,
                              containerView.bounds.size.width, containerView.bounds.size.height * 2 / 3);
        case UIInterfaceOrientationLandscapeLeft:
            return CGRectMake(0, - containerView.bounds.size.height * 2 / 3,
                              containerView.bounds.size.height, containerView.bounds.size.height * 2 / 3);
        case UIInterfaceOrientationPortraitUpsideDown:
            return CGRectMake(- containerView.bounds.size.width * 2 / 3, 0,
                              containerView.bounds.size.width * 2 / 3, containerView.bounds.size.height);
        case UIInterfaceOrientationPortrait:
            return CGRectMake(containerView.bounds.size.width, 0,
                              containerView.bounds.size.width * 2 / 3, containerView.bounds.size.height);
        default:
            return CGRectZero;
    }

}

- (CGRect)rectForPresentedStateEnd:(id<UIViewControllerContextTransitioning>)transitionContext
{
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIView *containerView = [transitionContext containerView];

    
    switch (toViewController.interfaceOrientation)
    {
        case UIInterfaceOrientationLandscapeRight:
            return CGRectOffset([self rectForPresentedStateStart:transitionContext], 0, - containerView.bounds.size.height * 2 / 3);
        case UIInterfaceOrientationLandscapeLeft:
            return CGRectOffset([self rectForPresentedStateStart:transitionContext], 0, containerView.bounds.size.height * 2 / 3);
        case UIInterfaceOrientationPortraitUpsideDown:
            return CGRectOffset([self rectForPresentedStateStart:transitionContext], containerView.bounds.size.width * 2 / 3, 0);
        case UIInterfaceOrientationPortrait:
            return CGRectOffset([self rectForPresentedStateStart:transitionContext], - containerView.bounds.size.width * 2 / 3, 0);
        default:
            return CGRectZero;
    }
}

On portrait mode and upside down everything seems to work fine. The issue is on landscape.

  1. When the devices orientation is UIInterfaceOrientationLandscapeLeft the view disappears for a second just before the transition starts.

  2. When the devices orientation is UIInterfaceOrientationLandscapeRight I get the following issue: The navigation bar is smaller and turns to normal when the transition ends like in the pictures

Issue with navigation bar when transition occurs

Issue with navigation bar when transition occurs

After transition is completed

After transition is completed

I am not sure if these are bugs from apple or if I am doing something wrong and if so how can I fix the issues?

Community
  • 1
  • 1
alecnash
  • 1,741
  • 1
  • 18
  • 42
  • i hope this will help you http://stackoverflow.com/questions/17794037/interface-builder-what-are-the-uiviews-layout-ios-6-7-deltas-for – Arun Jul 17 '14 at 09:56
  • @Spynet I tried changing it in my table view but unfortunately without any change – alecnash Jul 17 '14 at 10:08
  • still it looks same or some extra behaviour…. – Arun Jul 17 '14 at 10:09
  • @Spynet looks exactly the same. And it looks also the same when I use the autolayout – alecnash Jul 17 '14 at 10:12
  • can u explain little bit more do u have 2 tables or 1 and – Arun Jul 17 '14 at 10:13
  • on the test project I just have one table and create a new instance of it when a cell is being clicked. On my main project I have 2 but I get the same behaviour – alecnash Jul 17 '14 at 10:14
  • if 2 tables means why 1 have adobt the delta value why not adopt the second…. – Arun Jul 17 '14 at 10:14
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/57481/discussion-between-alecnash-and-spynet). – alecnash Jul 17 '14 at 10:15

2 Answers2

3

It is definitely an apple bug. For presenting the animation I am using something like this:

if (self.presenting) {
        toViewController.view.frame = [self rectForPresentedStateStart:transitionContext];
        [transitionContext.containerView addSubview:toViewController.view];
        [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
            fromViewController.view.frame = [self rectForDismissedState:transitionContext];
            toViewController.view.frame = [self rectForPresentedStateEnd:transitionContext];
        } completion:^(BOOL finished) {
            [transitionContext completeTransition:YES];
        }];    
}

The problem with the navigation controller is fixed if I add the view ( [transitionContext.containerView addSubview:toViewController.view]; ) after the animateWithDuration method. Still cannot figure out why.

alecnash
  • 1,741
  • 1
  • 18
  • 42
0

I guess, your containerView is UIWindow. So it's bounds is orientation independent so containerView.bounds.size.height is the same in portrait and landscape.

If I'm right you need to use width as height and height as width in landscape

ad1Dima
  • 3,075
  • 2
  • 23
  • 36
  • Not exactly. It's not like UIWindow. The axis doesn't stay put in the upper left corner when rotating. So everything should be adjusted accordingly. – alecnash Jul 25 '14 at 07:36