I\'m working on an app where having a \"drawer\" on the left-hand side would be very beneficial. I\'m doing some initial testing to see how I would best accomplish this, and I\'
I think your crash had to do with the indeterminate state problems you can get with UIKit whenever you put the main thread under load or are in the middle of a view transition. When you retrieve your values for your mathematical calculation your in the animation block vs outside the block, they are different contexts to access the UIView model, so I'm not surprised in the animation context you getting a memory error in that case.
After playing around with this a bunch and banging my head against the wall, I finally came to the conclusion that my code wasn't wrong unless I misunderstood something about blocks. Stepping through my code in debug yielded answers exactly like I expected, but between the end of the animation block and the beginning of the completion block, an EXC_BAD_ACCESS kept popping up.
Anyway, I'm not sure where I got the idea, but I figured I might want to try doing my mathematical calculations (for changing the frames) outside of my animation block.
Guess what? IT WORKED!
So, without further ado, here's the working code for what I wanted:
- (IBAction)showHidePressed:(id)sender
{
switch ([self CurrentState]) {
case kShown:
{
// Hide the panel and change the button's text
CGRect currLeftPanelRect = [[self LeftPanel] frame];
currLeftPanelRect.origin.x -= currLeftPanelRect.size.width / 2;
CGRect currRightPanelRect = [[self RightPanel] frame];
currRightPanelRect.origin.x = 0;
currRightPanelRect.size.width += currLeftPanelRect.size.width;
// 1. Hide the panel
[UIView animateWithDuration:0.5
animations:^{
// b. Move left panel from (0, 0, w, h) to (-w, 0, w, h)
[[self LeftPanel] setFrame:currLeftPanelRect];
// c. Expand right panel from (x, 0, w, h) to (0, 0, w + x, h)
[[self RightPanel] setFrame:currRightPanelRect];
}
completion:^(BOOL finished){ if(finished) {
[[self ShowHideButton] setTitle:@"Show Panel" forState:UIControlStateNormal];
[self setCurrentState:kHidden];
}
}];
}
break;
case kHidden:
{
// Show the panel and change the button's text
// 1. Show the panel
[UIView animateWithDuration:0.5
animations:^{
// b. Move left panel from (-w, 0, w, h) to (0, 0, w, h)
CGRect currLeftPanelRect = [[self LeftPanel] frame];
currLeftPanelRect.origin.x += currLeftPanelRect.size.width / 2;
[[self LeftPanel] setFrame:currLeftPanelRect];
// c. Expand right panel from (0, 0, w, h) to (leftWidth, 0, w - leftWidth, h)
CGRect currRightPanelRect = [[self RightPanel] frame];
currRightPanelRect.origin.x = currLeftPanelRect.size.width;
currRightPanelRect.size.width -= currLeftPanelRect.size.width;
[[self RightPanel] setFrame:currRightPanelRect];
}
completion:^(BOOL finished){ if(finished) {
[[self ShowHideButton] setTitle:@"Hide Panel" forState:UIControlStateNormal];
[self setCurrentState:kShown];
}
}];
}
break;
default:
break;
}
}