execute code only after view controller was dismissed - swift

Is there any way to make sure resetScene() gets called only after the view controller vc has been dismissed? Any help would be appreciated.
vc.present(activityVC, animated:true, completion: nil)
self.resetScene()

to make sure resetScene() gets called only after the view controller vc has been dismissed
Put the call to resetScene() inside the view controller vc's viewDidDisappear.
Or put it inside self's viewDidAppear and check first to make sure that the reason why we are reappearing is that vc was dismissed.

Related

view(Will/Did)Disappear not called when using modalPresentationStyle = formSheet

I have a UIViewController, MainViewController, that presents a SheetViewController using modalPresentationStyle = .formSheet. SheetViewController then presents another ViewController using modalPresentationStyle = .fullScreen. Doing this causes viewWillDisappear() to be called on SheetViewController, but never on MainViewController.
Since I have some frequent calls to a backend in MainViewController, I want to be informed when it is not visible, such that I can stop these calls. This could be done using delegates, but can it really be that there is no way that MainViewController can be informed directly by iOS when it is no longer visible on the screen?
The issue is related to how you are manipulating the view hierarchy.
If you present a VC using modalPresentationStyle = .fullScreen, UIKit removes the presenting controller.
If you present a VC using modalPresentationStyle = .formSheet, UIKit DOES NOT remove the presenting controller.
So...
From MainVC, present SheetVC as .formSheet ... MainVC is still in the hierarchy.
From SheetVC, present FullScreenVC as .fullScreen ... SheetVC is the presenting controller, so it is removed from the hierarchy -- but MainVC is still where it was.
When you dismiss FullScreenVC, SheetVC is again added to the view hierarchy, on top of MainVC.

Dismiss View when Label is pressed in TableViewCell

i have a label with a TapGesture in a table view cell that should dismiss the view controller, which is embedded in a Navigation controller, if its pressed.
Normally I would do it like that:
_ = navigationController?.popViewController(animated: true)
OR
self.dismiss(animated: true)
But this is not working inside the table view cell class.
Would be great if someone could help me!
For it to work you should pass that obligation to the viewController which is managing your tableView. So above your tableViewCell class declare a protocol with a function which the delegate (In this case the ViewController which is holding your tableView) should implement when called. So when a delegate gets called inside a ViewController dismiss the ViewController if it was modally presented and pop it if it was pushed, so one of the methods you mentioned above should work. If you Don't know how custom protocols work, try reading this article https://medium.com/#aapierce0/swift-using-protocols-to-add-custom-behavior-to-a-uitableviewcell-2c1f09610aa1

How to get rid of navigation controller and segue to a controller before it?

Say I have a storyboard a such logInVC->navViewController->RootVC->restOfStack
If in the rootVC I want to logOut, thereby segueing to logInVC without logInVC becoming a part of my stack then how would I do this. I essentially need to get rid of the navigation controller and its stack entirely, returning to the apps launch page that comes before the navVC.
Was surprised to have trouble finding an answer to this one in Swift, would think this is quite a common problem.
By dismissing the root view controller of your key window, you dismiss all view controllers and go back to youe login vc assuming it's the initial view controller.
UIApplication.sharedApplication().keyWindow?.rootViewController?.dismissViewControllerAnimated(true, completion: nil)
You cannot push a ViewController without NavigationController. But there are few ways to achieve what you need.
Make your Login ViewController as RootViewController.
The closest alternative if you don't want to use navigation controller are ModalView controllers.
To present the controller:
self.presentViewController(controller, animated: true, completion: nil)
To dismiss the controller:
self.dismissViewControllerAnimated(true, completion: {});

viewDidLoad method is calling again after setting nil to tableView in UITableViewController in iOS

I am using UITableViewController in my applicaton. While pop from tableview controller to back, i was setting nil to table view to deallocate the view controller from memory. its again calling viewDidLoad, please explain me why it is happening.
-(void)handleBackButton{
self.tableView=nil;
[self.navigationController popViewControllerAnimated:YES];
}
You could set a breakpoint in viewDidLoad and look at the stack trace to see why it's reloading its view.
But I can make an educated guess. When you tell the navigation controller to pop a view controller, it needs to animate that view controller's view off the screen. To do so, it probably asks the disappearing view controller for its view.
A UITableViewController's view is the same as its tableView. When you set tableView to nil, you also set view to nil. So when the navigation controller asks the table view controller for its view (so it can animate the view off the screen), the table view controller notices that its view is nil, so it loads its view. And to load its view, it sends itself loadView and then it sends itself viewDidLoad.
I don't know why you would really bother trying to unload the view. If the view controller itself gets deallocated, it will release its view (which will deallocate the view unless you've retained it somewhere else). And if the view controller doesn't get deallocated, isn't that usually because you might want to put its view back on the screen soon?
Anyway, if you really want to get rid of a view controller's view, don't set its view to nil while the view might still be in the on-screen view hierarchy. Wait until the view is definitely out of the hierarchy. For example, subclass UITableViewController, and override didMoveToParentViewController: like this:
- (void)didMoveToParentViewController:(UIViewController *)parentViewController {
[super didMoveToParentViewController:parentViewController];
if (parentViewController == nil) {
self.tableView = nil;
}
}

Dismiss pushed view from within Navigation Controller

I have a Navigation Controller with a View Controller displaying a button. The button is linked to another View Controller using a push segue which automatically adds a top navigation bar with a back button. This all works fine. Pressing the back button slides off the 2nd view and returns to the 1st.
I have a button on the 2nd View Controller, that when pressed runs some code and a delegate call back to the 1st View Controller. Again this works fine.
Now I just need to dismiss the 2nd pushed View from code as if the back button was pressed.
I have tried using dismissModalViewCcontrollerAnimated and dismissViewControllerAnimated, however they both dismiss the whole Navigation Controller which removes view 2 and 1 (returning bak to my main menu).
Whats the correct way to slide off the view.
Obtain a reference to your UINavigationController and call
- (UIViewController *)popViewControllerAnimated:(BOOL)animated
on it.
In Swift it would be calling the method
navigationController?.popViewController(animated: true)
If we use push segue, then use popViewController
#IBAction func backButtonClicked(_ sender: Any) {
self.navigationController?.popViewController(animated: false)
}
In swift you can also call:
self.navigationController?.popToRootViewControllerAnimated(true)
On Objective-C is
[self.navigationController popViewControllerAnimated:YES];
for a jump to the first root controller
[self.navigationController popToRootViewControllerAnimated:YES];
or is a possible move to the specific controller
[self.navigationController popToViewController:(nonnull UIViewController *) animated:(BOOL)];
animation specific animation process of move the controller. If the animation is false the controller will appear without animations.
The UIViewController must be from one which is on the stack.
If NavViewController is used with UIModalPresentationFullScreen then the below line will work
self.navigationController?.dismiss(animated: true, completion: nil)