Objective-C中侧边菜单:主视图与侧视图向左滑动返回的实现方法
Hey there! Let's get that side menu close animation sorted out. You've already nailed the open flow, so let's build on that with a clean, smooth close transition.
First, a quick tweak to your open code to make it more robust (and easier to hook up the close logic):
- Let's use a property to keep a reference to your side view controller instead of a local variable (this avoids messy direct instance variable access like
self->sampleand lets us access it later for closing) - Fix the side view's initial position so it slides in properly — right now it's just appearing instantly instead of sliding from the left
Here's the updated open action:
// First, add this property to your view controller's header or class extension @property (nonatomic, strong) UIViewController *sideViewController; - (IBAction)showSideView:(id)sender { NSLog(@"sideview button pushed"); // Animate main view to the right [UIView animateWithDuration:0.5f animations:^{ self.view.frame = CGRectOffset(self.view.frame, 243, 0); // Add shadow effect self.view.layer.shadowColor = [UIColor whiteColor].CGColor; self.view.layer.shadowOpacity = 0.8; self.view.layer.shadowRadius = 3.0; self.view.layer.shadowOffset = CGSizeMake(-2.0, -2.0); }]; // Initialize side view controller self.sideViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"side"]; // Start side view off-screen to the left CGRect sideViewFrame = self.view.bounds; sideViewFrame.origin.x = -sideViewFrame.size.width; self.sideViewController.view.frame = sideViewFrame; [self.view.window addSubview:self.sideViewController.view]; // Animate side view sliding in from the left [UIView animateWithDuration:0.5f animations:^{ self.sideViewController.view.frame = self.view.bounds; }]; }
Now, let's add the close action. This will animate the main view back to its original position, slide the side view off-screen to the left, then clean up the subview and shadow:
- (IBAction)hideSideView:(id)sender { NSLog(@"close sideview button pushed"); // Get the original frame of the main view (before sliding right) CGRect originalMainFrame = CGRectOffset(self.view.frame, -243, 0); // Animate main view back to original position, and side view off-screen [UIView animateWithDuration:0.5f animations:^{ self.view.frame = originalMainFrame; // Remove shadow effect smoothly self.view.layer.shadowOpacity = 0.0; // Slide side view back to the left off-screen CGRect sideViewFrame = self.sideViewController.view.frame; sideViewFrame.origin.x = -sideViewFrame.size.width; self.sideViewController.view.frame = sideViewFrame; } completion:^(BOOL finished) { // After animation completes, remove the side view from window to free up memory [self.sideViewController.view removeFromSuperview]; self.sideViewController = nil; }]; }
Key Notes:
- Using a property for the side view controller lets us easily reference it when we need to close it
- The completion block in the close animation ensures we only remove the side view after the animation finishes, which looks much cleaner
- We're animating the shadow opacity back to 0 instead of just removing the shadow properties, which gives a smoother transition
- The side view starts off-screen on open, so its slide-in animation is consistent with the slide-out on close
You can hook up the hideSideView: action to a button in your side view, or even add a tap gesture recognizer to the main view to trigger closing when the user taps outside the side menu.
内容的提问来源于stack exchange,提问作者stefanosn

