viewDidAppear not being triggered after initial load - swift

Currently running into an issue where I am trying to update my view after using a show segue to a separate popup view. The initial viewDidAppear is being triggered on load, but after i close out of my other view and transition back to the other view, it is not reloading.
I'm looking for an option to either trigger a reload of my data, or to try and refresh the information on a view being closed.

When you close out of the view controller, are you dismissing it or performing a new segue. If you are just performing a new segue, then the view controller would have already been loaded. You would need to use this function:
override func dismissViewControllerAnimated(flag: Bool, completion: (() -> Void)?) {
}

Try calling the reloadData() method on the tableview IBOutlet from within the button being clicked to segue to the viewController.
for Ex:
#IBAction func segueButton(sender: AnyObject) {
tableView.reloadData()
}

Related

Close a modal view with a button in Swift?

Learning some view controller basics and am stuck on how to dismiss a modal with a button.
In my slimmed-down example, I have a two view setup with the initial view and the modal. The first view has a button that successfully pops up the modal. On the modal, there is a button that should dismiss itself.
According to other posts and documentation, I should be able to run simple code attached to the button like this:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func CloseModal(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
}
}
When I tap the "Close Modal" button nothing happens. What am I missing here? Am I putting this code in the wrong place? Currently, it's in the main ViewController.swift file.
The other approach is to use an unwind segue to your main view controller. Just add an “unwind action” in the first view controller:
class ViewController: UIViewController {
#IBAction func unwindHome(_ segue: UIStoryboardSegue) {
// this is intentionally blank
}
}
Just give this unwind action a meaningful name, unwindHome in this example, so that, if and when you have multiple unwind actions later on, you can easily differentiate between them.
Then you can control-drag from the button in the second scene to the “exit” control and select the appropriate unwind action:
This has a few nice aspects:
The “close” button no longer cares how you presented it, it will unwind however is appropriate (e.g. if you later change the initial segue to be a show/push segue, the unwind segue will still work without any code changes).
Because you’re now using a segue to unwind, the presented view controller can use its prepare(for:sender:) to send data back, should you eventually need to do that.
If you want, you can unwind multiple scenes. For example if A presents B, and B presents C, you can obviously unwind from C to B, but you can also unwind all the way from C to A if you want.
So, while dismiss works, unwind segues are another alternative.
You actually have two ViewController screens, but it looks like you have one ViewController class? And is the 2nd screen connected to a class?
Must be in the class that belongs to the second screen of the closeModal method.
//This is First ViewController, OpenModal Button is here
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
// The name of the class and the Viewcontroller in the storyboard have to be the same, and CloseModol Button and function need to be here
class SecondViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func CloseModal(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
}
}
Don't forget to set the name of the ViewController in Storyboad;
from FirstViewController to SecondViewController

How to reload previews ViewCotroller when user dismisses sheet presentations

I am using sheet presentation to view settings view iOS13.when the user dismisses or closes the view I want to trigger reload to previews viewController to update the view.
I tried viewWillAppear in previews ViewController but No user
note even viewDidLoad
how to force previews viewController in sheet presentation?
Override the dismiss function in your settings View Controller and write a delegate to send the reload action.
Assign the delegate to the view controller that you want to send the reload information.
protocol MyViewControllerDelegate: class {
func myViewControllerDidDismiss()
}
class MyViewController: UIViewController {
weak var delegate: MyViewControllerDelegate?
override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
self.delegate?.myViewControllerDidDismiss()
super.dismiss(animated: flag, completion: completion)
}
}
Other way is making the protocol and overriding viewDidDisappear and send the delegate method when the settings view controller execute the viewDidDisappear. Feel free!

iOS 13 Modals - Calling swipe dismissal programmatically

I'd like to detect a modal dismissal in the view controller that's presenting the modal.
This method works amazing for detecting the new iOS 13 swipe dismissal on the new card modals:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "MyIdentifier" {
segue.destination.presentationController?.delegate = self
}
}
extension MyController: UIAdaptivePresentationControllerDelegate {
func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
//clean up UI (de-selecting stuff) once modal has been dismissed
}
}
However, presentationControllerDidDismiss is NOT called if the modal dismisses itself programmatically through an action:
#IBAction func btnDismissTap(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
}
Is this a bug or is there a way I can programmatically call whatever the "swipe" dismiss is so I can detect all dismissals the same way? Currently I'm writing extra "dismiss" delegate methods into my modals as a work around and it seems unnecessary.
However, presentationControllerDidDismiss is NOT called if the modal dismisses itself programmatically through an action
self.dismiss(animated: true, completion: nil)
It doesn’t need to be called, because you dismissed the modal yourself, in code. You cannot not know that the modal was dismissed. You don’t need to receive a dismissal signal, because you gave the dismissal signal in the first place.
You typically don’t get a delegate method call reporting something your own code did. Delegate methods report user actions. It would be crazy if everything you yourself did in code came back as a delegate method call.
Mojtaba Hosseini, answer is something I was looking for.
Currently, I need to write a delegate function to let the presenting view know that the user dismissed the modal PLUS do the presentationControllerDidDismiss handler for swipe dismissals:
#IBAction func btnDismissTap(_ sender: Any) {
self.dismiss(animated: true, completion: {
self.delegate?.myModalViewDidDismiss()
})
}
I wanted to handle both of these the same way and Mojtaba's answer works for me. However, presentationControllerDidDismiss does not get invoked if you call it inside of the self.dismiss completion block, you need to call it before.
I adapted my code to use "presentationControllerWillDismiss" (for clarity) and simply called the delegate before I dismiss programmatically in my modals and it works great.
#IBAction func btnDismissTap(_ sender: Any) {
if let pvc = self.presentationController {
pvc.delegate?.presentationControllerWillDismiss?(pvc)
}
self.dismiss(animated: true, completion: nil)
}
Now, I no longer need to create delegate functions to handle modal dismissals in code and my swipe handler takes care of all scenarios.
FYI, what I'm "handling" is doing some UI clean up (de-selections, etc) on the presenting UI once the modal is dismissed.
As #matt mentioned, there is no need to inform the one who dismissed a view by delegate. Because it is already known. BUT if you need that delegate method to be called, you should call it manually your self after dismissing the view:
#IBAction func btnDismissTap(_ sender: Any) {
self.dismiss(animated: true) {
presentationController?.delegate?.presentationControllerDidDismiss?(presentationController!)
}
}

How to unwind to home, and then segue forward in one action

I want to tap the "Go To DestinationVC" button in the SourceVC, and have it safely unwind back home, and then segue forward via a different route to the DestinationVC.
I tried just calling a performSegue in side the unwinding segue function:
#IBAction func UnwindAndSegueToDestination(_ segue: UIStoryboardSegue) {
performSegue(withIdentifier: "SegToDest", sender: nil)
}
However, this results in the DestinationVC briefly loading, and then being replace with the HomeVC.
I would recommend putting it in the viewDidAppear of the HomeVC if doing it the way you described isn't working. I would pass a Bool value during the unwind segue that tells the Home VC to triggers a segue in the viewDidAppear. Once that segue is triggered, make sure to set that Bool value to false again. Obviously the Bool value would be passed in the prepare to segue method in the source VC.

Automatically Reload TableViewController On Rewind

I am working on an app where it starts out at a tableViewController which loads and displays data stored in a Realm database. I have it so I can create a new entry in my Realm database in a separate scene and the save button unwind segues back to the initial tableView.
I current have it so the tableViewController will reload the tableView on pull down (something I Learned here, second answer down) but I would be better if the tableView would reload its self automatically upon unwind, displaying all the data in my database, including my new entry. Could someone please direct me to a tutorial that will teach me how this is done.
Additional info: My app is embedded in a navigation controller. The save button is located the bottom tool bar.
You can use NSNotification for that.
First of all in your tableViewController add this in your viewDidLoad method:
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "refreshTable:", name: "refresh", object: nil)
}
And this will call one method from your class:
func refreshTable(notification: NSNotification) {
println("Received Notification")
tableView.reloadData() //reload your tableview here
}
So add this method too.
Now in your next view controller where you add new data into data base add this in you unWindSegue function:
NSNotificationCenter.defaultCenter().postNotificationName("refresh", object: nil, userInfo: nil)
Hope it will help
Try reloading your tabledata in viewWillAppear in initial (tableview)controller.
override func viewWillAppear(animated: Bool) {
self.tableView.reloadData()
}
Or call again the function through which you are loading your data from Realm like
override func viewWillAppear(animated: Bool) {
getMyData() //or whatever your function name is
}
If you are using storyboard unwind segue, try using
func unwindSegue(segue:UIStoryboardSegue) {
if segue.identifier == "identifier" {
getData()
self.tableView.reloaddata()
}
}