I am using a custom controller for transitions (could not use navigation controller due to inherent cycles in project, which would allow the navigation controllers stack to grow unbounded [which I assume would cause memory issues]). I am emulating a navigation controllers sliding animation (when transitioning to new screens) using UIView animateWithDuration:animations:completion:
When a button triggering the transition is pressed, the frame of the new view I want to transition to is set to an offscreen position. In the animation for the transition (UIView animateWithDuration:animations:completion:), the view currently on screen has its frame set to an offscreen position, and the new view is set to an onscreen position.
This is inside my custom controller for transitions:
CGFloat windowWidth = self.mainView.frame.size.width;
CGFloat windowHeight = self.mainView.frame.size.height;
CGRect offScreenLeft = CGRectMake(-1*windowWidth, 0.0, windowWidth, windowHeight);
CGRect onScreen = self.mainView.frame;
CGRect offScreenRight = CGRectMake(windowWidth, 0.0, windowWidth, windowHeight);
if (direction == TransitionDirectionForward)
{
if (dragBackgroundOnscreen){
[self.mainView addSubview:self.backgroundView];
[self.mainView sendSubviewToBack:self.backgroundView];
self.backgroundView.frame = offScreenRight;
}
self.currentViewController.view.frame = offScreenRight;
[UIView animateWithDuration:0.65
animations:^{
oldViewController.view.frame = offScreenLeft;
if (dragBackgroundOffscreen)
self.backgroundView.frame = offScreenLeft;
else if (dragBackgroundOnscreen)
self.backgroundView.frame = onScreen;
self.currentViewController.view.frame = onScreen;
}
completion:^(BOOL finished){
[oldViewController.view removeFromSuperview];
if (dragBackgroundOffscreen)
[self.backgroundView removeFromSuperview];
[oldViewController willMoveToParentViewController:nil];
[oldViewController removeFromParentViewController];
[self.currentViewController didMoveToParentViewController:self];
}];
}
else if (direction == TransitionDirectionBackward)
{
if (dragBackgroundOnscreen){
[self.mainView addSubview:self.backgroundView];
[self.mainView sendSubviewToBack:self.backgroundView];
self.backgroundView.frame = offScreenLeft;
}
self.currentViewController.view.frame = offScreenLeft;
[UIView animateWithDuration:0.65
animations:^{
oldViewController.view.frame = offScreenRight;
if (dragBackgroundOffscreen)
self.backgroundView.frame = offScreenRight;
else if (dragBackgroundOnscreen)
self.backgroundView.frame = onScreen;
self.currentViewController.view.frame = onScreen;
}
completion:^(BOOL finished){
[oldViewController.view removeFromSuperview];
if (dragBackgroundOffscreen)
[self.backgroundView removeFromSuperview];
[oldViewController willMoveToParentViewController:nil];
[oldViewController removeFromParentViewController];
[self.currentViewController didMoveToParentViewController:self];
}];
}
I also want the background (self.backgroundView) to remain static unless moving to a screen that has its own background (i.e. I dont want the background to slide if the new views background is the same background).
I am using TransitionDirectionBackward and TransitionDirectionForward just to differentiate between sliding left and sliding right.
Everything works great, except when transitioning involves a GMGridView. the problem when the Gridviews frame is set to an offscreen frame its really setting its currently selected page's frame to that offscreen frame. Other pages of the gridview are not bounded by this frame, so they can appear on screen even before the transition. I tried setting the frame and bounds property on the GridView's viewcontroller's view, but I can still get a page of the gridview appearing onscreen before the transition animation.
Anyone see a solution to this? I was trying to find a way to clip the view of the GridView during the transition so pages dont appear except for the currently selected page, but havent found anything useful.
UPDATE: I found a possible fix by setting alpha = 0.0 for cells that are visible but shouldnt be (later setting alpha = 1.0 when the transition animation is complete). However, I need to know which cells to do this for. I need a way to access the page that the GMGridView is currently on so I can set the adjacent page's cells to have an alpha of 0.0.
UPDATE: Found a way to get it to work by using myGridView convertPoint:(A cgpoint i found by trial and error to be on the first cell of a page.) fromView:myGridView.window. NOTE: I needed an if/else if to check if i was in lanscape left or landscape right since the window coordinates do not rotate when the device is rotated. with this i was able to get the index of the cell at the point on the screen i had specified and then set the previous page to be transparent until after the transition animation.
I would still like to know if there is a way of "clipping" the gridview so that if the cells could be opaque, but just never displayed....?