present与push ViewController的区别及dismissViewController失效问题求助
Hey there! Let's break this down step by step—first clarifying the difference between present and push, then fixing your dismissViewController issue, and finally getting that data transfer working properly.
present and push View Controllers These two methods handle view controller navigation in fundamentally different ways:
- Navigation Stack Behavior:
pushViewController:animated:Adds the new VC to the navigation stack managed byUINavigationController. To go back, you usepopViewControllerAnimated:(orpopToRootViewControllerAnimated:), which removes VCs from the stack one at a time.presentViewController:animated:completion:Presents the new VC modally (it sits on top of your existing VC hierarchy, not part of the navigation stack). You dismiss it withdismissViewControllerAnimated:completion:to remove this overlay.
- Visual & UI Context:
- Push uses the standard slide-in from the right (default navigation animation), and the new VC automatically gets a back button in the navigation bar.
- Present uses a slide-up animation (default), and modally presented VCs don’t get a back button by default—you’ll need to add your own dismiss trigger if needed.
dismissViewControllerAnimated: Isn’t Working The core issue here is mismatched presentation/dismissal methods. If you used pushViewController: to navigate to your current VC, that VC is part of the navigation stack—not a modal presentation. dismissViewControllerAnimated: only works for VCs that were presented with presentViewController:.
That’s exactly why popViewControllerAnimated: works: it’s the correct method to remove a pushed VC from the navigation stack.
Let’s cover two scenarios based on how you actually navigated to the current VC:
Scenario 1: You used pushViewController: (Navigation Stack)
Since pop is the right way to go back here, we’ll use a delegate pattern (the standard iOS approach) to pass data back to your HomeVC.
Step 1: Define a Delegate Protocol
In your current VC’s header file, create a protocol to define the data transfer method:
@protocol CurrentVCDelegate <NSObject> - (void)didFinishWithData:(NSString *)displayText; @end @interface CurrentVC : UIViewController @property (nonatomic, weak) id<CurrentVCDelegate> delegate; @end
Step 2: Set the Delegate in HomeVC
When you push the current VC from HomeVC, set HomeVC as the delegate:
// When navigating to CurrentVC CurrentVC *vc = [[CurrentVC alloc] init]; vc.delegate = self; [self.navigationController pushViewController:vc animated:YES];
Step 3: Implement the Delegate Method in HomeVC
Add this method to HomeVC to receive and use the data:
- (void)didFinishWithData:(NSString *)displayText { self.IdNameLabel.text = displayText; }
Step 4: Trigger Pop + Data Transfer
In your current VC, when you want to go back, call the delegate method first then pop:
// 'display' is your data string to pass back if (self.delegate && [self.delegate respondsToSelector:@selector(didFinishWithData:)]) { [self.delegate didFinishWithData:display]; } [self.navigationController popViewControllerAnimated:YES];
Scenario 2: You Meant to Use presentViewController: (Modal)
If you intended to present the VC modally, first fix how you present it (wrap it in a navigation controller if you need a navigation bar):
CurrentVC *vc = [[CurrentVC alloc] init]; UINavigationController *navVC = [[UINavigationController alloc] initWithRootViewController:vc]; [self presentViewController:navVC animated:YES completion:nil];
Then use the same delegate pattern as above:
- Set
HomeVCas the delegate when presenting. - In your current VC, call the delegate method then dismiss:
if (self.delegate && [self.delegate respondsToSelector:@selector(didFinishWithData:)]) { [self.delegate didFinishWithData:display]; } [self dismissViewControllerAnimated:YES completion:nil];
Why Your Original Data Passing Failed
Your line HomeVC *loading; loading.IdNameLabel.text=display; creates a new, uninitialized instance of HomeVC—not the one that’s actually on screen. That’s why the text didn’t update: you were modifying a VC that wasn’t presented. Delegates solve this by letting you communicate directly with the existing HomeVC instance.
- Use
push+popfor navigation stack VCs,present+dismissfor modals—never mix them. - Always use delegates (or blocks) to pass data back to a parent VC—never create a new instance of the parent to modify its UI.
内容的提问来源于stack exchange,提问作者user9137841

