How to reload previews ViewCotroller when user dismisses sheet presentations - swift

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!

Related

Check if Popped UIViewController gets dismissed by swipe

I want to check whenever the user swipes a popped viewController away. So for example when in whatsApp a user exits the current chat by swiping from the edge. How is that possible in Swift?
I don't want to use viewDidDisappear, because this method also gets called when another viewController is presented over the current viewController.
As I wrote in comment, a simple workaround would be in viewDidDisappear, check if the navigationController is nil.
class MyVc: UIViewController {
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
if navigationController == nil {
print("view controller has been popped")
}
}
}
Of course, this solution works only if the view controller is embedded into a navigation controller, otherwise the if statement will always be true.
This "swipe" is handled by the interactivePopGestureRecognizer of the UINavigationController. It is possible to set the delegate of this gesture recognizer to your UIViewController as follows:
navigationController?.interactivePopGestureRecognizer?.delegate = self
Then, you can implement the UIGestureRecognizerDelegate in your UIViewController. This would look like this:
extension YourViewController: UIGestureRecognizerDelegate {
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
guard gestureRecognizer.isEqual(self.navigationController?.interactivePopGestureRecognizer) else { return true }
print("The interactive pop gesture recognizer is being called.")
return true
}
}
I haven't tested the code, but this should print every time the interactivePopGestureRecognizer is used.
For more information, refer to the documentation of the interactivePopGestureRecognizer and UIGestureRecognizerDelegate.

How can I reload the tableView after dismissal of modal view? [duplicate]

This question already has answers here:
Detecting sheet was dismissed on iOS 13
(13 answers)
Closed 1 year ago.
In StoreViewController, when a button is clicked, a ModalViewController, named AddStoreVC is opened.
Then at AddStoreVC, when I press Save, I want to dismiss itself (which I can) and when StoreViewController is loaded, the tableView to be refreshed.
viewWillAppear, viewDidAppear or none of the alternatives on previous threads are applicable.
I'd appreciate for your support.
You can use a closure, delegate or notifications (and even KVO would also be a solution). Since you have a relation of one-one, I'd go with closure or pattern.
Closure:
Add in the ViewController which will be modally presented (AddStoreVC)
var onWillDismiss: (() -> Void)?
When you call dismiss(animated:completion:) on it, call onWillDismiss?()
In the presenting ViewController, get a reference on the modal one, and do:
modalVC.onWillDismiss = { [weak self] in
self?.myTableView.reloadData()
}
I passed no param (()), but if you also want to retrieve a param, add it. Imagine you want an Int:
var onWillDismiss: ((Int) -> Void)?
onWillDismiss?(theIntIWantToPass)
modalVC.onWillDismiss = { [weak self] theIntPassed in
print(theIntPassed)
self?.myTableView.reloadData()
}
Delegate :
You can also use the delegate pattern:
Create the delegate:
protocol AddStoreVCCustomProtocol {
func modalVCWillDismiss(_ modalVC: AddStoreVC)
func modalVC(_ modalVC, willDimissWithParam param: Int)
}
Make the presenting one compliant to it:
extension StoreViewController: AddStoreVCCustomProtocol {
func modalVCWillDismiss(_ modalVC: AddStoreVC) {
myTableView.reloadData()
}
func modalVC(_ modalVC, willDimissWithParam param: Int) {
print("theIntPassed with delegate: \(param)")
myTableView.reloadData()
}
}
Add a property to the Modal to have a delegate:
weak var customDelegate: AddStoreVCCustomProtocol?
And call it on dismiss(animated:completion:): customDelegate?.modalVCWillDismiss(self) or `customDelegate?.modalVC(self, willDimissWithParam: theIntIWantToPass)

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 can I dismiss the parent view controller after the second view controller is launched?

I am working on an OSX app in swift which programmatically clicks a button to launch a view controller. I would like to dismiss the initial view controller programatically.
class ViewController: NSViewController {
#IBOutlet weak var button: NSButton!
override func viewDidLoad() {
super.viewDidLoad()
button.performClick(nil)
self.dismissViewController(self)
// Do any additional setup after loading the view.
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
}
Just to upgrade the previous answer
self.view.window?.close() doesn't work in swift 4 you might want to try the code below.
self.view.window?.rootViewController?.dismiss(animated: false, completion: nil)
It looks like your button isn't actually performing dismissViewController(). You're actually calling this method in your viewDidLoad(). It's also worth mentioning that you might want to try self.view.window?.close() instead.

viewDidAppear not being triggered after initial load

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()
}