When BackgroundClicked is triggered go back to the previous viewcontroller and programatically click on a button on the previous viewcontroller on the load. But only if BackgroundClicked was clicked from the child view controller
for example
//this button is on child controller
#IBAction func BackgroundClicked(sender: AnyObject)
{
self.navigationController?.popToRootViewControllerAnimated(true)
// when im on the root controller click button abc
// button abc resides on the root controller
}
I only want button abc clicked on the load of the root controller only if BackgroundClicked was clicked. I'm not sure how to go about this or if it's even possible
You can send a notification when button is pressed into your ChildViewController like show in below:
Add this code in your ChildViewController when you press a button:
#IBAction func BackgroundClicked(sender: AnyObject)
{
NSNotificationCenter.defaultCenter().postNotificationName("refresh", object: nil)
self.navigationController?.popToRootViewControllerAnimated(true)
}
In your ParentViewController add this code into your viewDidLoad method:
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "refreshList:", name:"refresh", object: nil)
}
and here is your helper function:
func refreshList(notification: NSNotification){
println("parent method is called")
}
Now when ever you press back button from your ChildViewController refreshList method will call from your ParentViewController.
Check THIS sample project for more Info.
Hope this will help.
So that will go back to the root view controller, but what you want to do is you want to create a function in the previous view controller. In the code in the viewController that you are going back to run the name of the function in the viewDidLoad() method. Also whenever you click the back button you want to change the value of a variable because you don't want to run the function every time int he viewDidLoad(). This is what the code to the previous view controller should look like:
var decideInt: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
if decideInt == 0 {
// Do Nothing
} else if decideInt == 1 {
functionYouWantToRun()
decideInt = 0
}
}
func functionYouWantToRun() {
//Write the code to the function you want to run
}
Here is the code that you need to write to go back:
//this button is on child controller
#IBAction func BackgroundClicked(sender: AnyObject)
{
self.navigationController?.popToRootViewControllerAnimated(true)
var goToView: DestinationViewControllerName = DestinationViewControllerName()
goToView.decideInt = 1
}
Related
I have a tableview, which is a list of football matches. In my navigation I have a "plus" sign where I can add a new match to. This is presented as a popover and it works very fine. Although when I use
dismiss(animated: true, completion: nil) and apply changes to my database.
The tableview does not update and I have to change page in the app, to make it update. '
Any suggesting for making my tableview updating after a popover has been showed? I have tried updating the tableview in viewDidAppear
When you dismiss your popover controller at that time check which is presenting view controller if it is your VC with tableview you want to reload then reload your tableview in viewWillDisappear method of your popoverVC
class PopOverViewController {
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if let tableVC = presentingViewController as? TableViewController {
DispatchQueue.main.async {
tableVC.tableView.reloadData()
}
}
}
If you want to reload data from a core data database
I don't know what data base you are using but I assume it's Core Data
If it's the case:
create un Unwind Segue (control drag the button you're using to dismiss the controller to the exit icon on top right of controller, give it an identifier).
add this code to both your tableview controller and popoverController
here is the code:
class TableViewController: UITableViewController {
var matches = [Match](){ //Core Data object
didSet {
OperationQueue.main.addOperation { //reloading after adding a new match (safe)
self.tableView.reloadData()
}
}
}
//...
//this unwind function executes after dismissing your popover controller
#IBAction func unwindToThemeList(sender: UIStoryboardSegue) {
matches = //... retreive your data
//this code works with var theme {didset} to make sure new matches are added
}
}
and
class popoverController: UIViewController {
//this section of code lets you do operations before dismissing the controller
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let identifier = segue.identifier else { return }
if identifier == TheNameYouGaveToYourIdentifier {
//Do your saves
}
}
So when you press the button to dismiss, it will trigger the unwind segue, going through override prepare first then through unwind for segue.
prepare section in pop viewController lets you do your saves
unwind section in tableviewController lets you retrieve your data
then to reload efficiently use the didst section
I am having a problem accessing my UIButton that's inside a ContainerView from another ViewController.
If the user taps the button a SubView should appear inside of my ViewController. I tried dragging the button in my ViewController file to create an #IBAaction func tapped() but that is not working.
It only works inside of the ContainerView.swift file. But I can not create my Subview there...
I hope you get my problem, I am grateful for every help!
import UIKit
class ContainerViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func addButtonTapped(_ sender: Any) {
print("add Button")
}
You can reach your ViewController inside your ContainerView using its parent property. So, inside your ContainerView class:
if let parentVC = self.parent as? ViewController {
parentVC.showSubView() // your method to show the sub view.
}
You can achieve this using NotificationCenter and Delegates. Here is how you can achieve it with NotificationCenter
In your ContainerViewController you can post notification on button click
#IBAction func yourBtnTap(sender : UIButton) {
NotificationCenter.default.post(name: Notification.Name("myBtnTapped"), object: nil)
}
In your CurrentViewController you have to first register to receive this notification. So in your viewDidLoad, do this:
NotificationCenter.default.addObserver(self, selector: #selector(self.myBtnTappedAction(notification:)), name: Notification.Name("myBtnTapped"), object: nil)
Now in your CurrentViewContoller create myBtnTappedAction function that will be called whenever the button is tapped.
#objc func myBtnTappedAction(notification : Notification) {
// now you can perform all your actions here. this function will be called everytime the button in the container view is tapped.
}
I have UITabBarController. From the Home tab, I segued to a ThankYouVC.
When I unwind from ThankYouVC, I want to change the selected tab.
What I've tried:
HomeVC
#IBAction func unwindToMain(segue:UIStoryboardSegue) {
print("unwind")
self.tabBarController?.selectedIndex = 0
}
The console log prints unwind, but doesn't change the index.
Another attempt:
enum Notifications: String, NotificationName {
case QRDoneNotification
}
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(unwindCallBack), name: Notification.Name("QRDoneNotification"), object: nil)
}
#IBAction func unwindToMain(segue:UIStoryboardSegue) {
print("unwind")
NotificationCenter.default.post(name: Notifications.QRDoneNotification.name, object: nil)
}
func unwindCallBack() {
self.tabBarController?.selectedIndex = 0
}
Still no luck!!
Help me out.
The problem is that an unwind segue unwinds to the view controller that holds the function. So that's where you end up.
One solution: subclass UITabBarController and put your unwind segue there.
class MyTabBarController: UITabBarController {
#IBAction func unwindToMain(segue:UIStoryboardSegue) {
print("Unwinding to the custom tab bar controller...")
selectedIndex = 1
}
}
So, add that class to your project... set the Custom Class of your current UITabBarController to MyTabBarController... Assign your Exit / Unwind segue to this new one, and don't forget to delete your existing unwindToMain() function and unwind connection.
In my swift app I have a UIViewController with a button. This button opens up the UIViewController number 2 and there user has another button. When user presses it - he opens UIViewController number 3. There is also a button and when user presses it - he calls the code:
self.dismissViewControllerAnimated(false, completion: nil)
and thanks to it the UIViewController number 3 disappears and user sees UIViewController number 2. My question is - is there a way of also dismissing the UIViewController number 2 so that user can come back smoothly from number 3 to number 1?
For now I created a function and call it through protocol:
UIViewController number 2:
protocol HandleYourFullRequest: class {
func hideContainer()
}
class FullRequest: UIViewController, HandleYourFullRequest{
func hideContainer(){
self.dismissViewControllerAnimated(false, completion: nil)
}
#IBAction func exitbuttonaction(sender: AnyObject) {
self.performSegueWithIdentifier("temporarySegue", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "temporarySegue"){
if let fullRequestDetails = segue.destinationViewController as? YourFullRequest
{
fullRequestDetails.delegateRequest = self
}
}
}
}
UIViewController number 3:
class YourFullRequest: UIViewController{
var delegateRequest:HandleYourFullRequest?
#IBAction func exitbuttonaction(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
delegateRequest?.hideContainer()
}
}
But with that solution when user presses the button - the UIViewController number 3 disappears and UIViewController number 2 appears for a second and disappears then. Is there a way of removing number 2 without showing it to the user and point him directly to the number 1?
I'm still unclear as two which button is wired to which action, but from what I can tell when the dismiss button is pressed on view controller 3 it calls self.dismissViewControllerAnimated(false, completion: nil) in view controller number 2.
Try putting this method in view controller 3.
#IBAction func exitButtonAction(sender: AnyObject) {
self.presentingViewController?.presentingViewController?.dismissViewControllerAnimated(true, completion: nil);
}
This will work assuming that both view controllers are presented and not pushed in something like a navigation controller.
You can use removeLast() function to pop controllers off the stack.
#IBAction func doneAction(sender: AnyObject) {
var vc = self.navigationController?.viewControllers
// remove controllers from the stack
vc?.removeLast()
vc?.removeLast()
// Jump back to the controller you want.
self.navigationController?.setViewControllers(vc!, animated: false)
}
You can use popToViewController(viewController: UIViewController, animated: Bool)
Where viewController is the viewController you wish to pop to, in your case, 'UIViewController number 1'.
popToViewController Documentation
If you don't have a reference to the View Controller, you can get it from self.navigationController.viewControllers, it will be the first object in your example.
There is a method on UINavigationController called setViewControllers. It takes an array of all the view controllers you want active. You can get all the view controllers on the stack as an array, remove the ones you don't want, then call setViewControllers with the updated array.
I have a TableViewController to handle my data and a sortFunction. What I want to do is to call the sortFunction in a SortViewController and when the Button "done" is clicked go back to my TableViewController (which should show the sorted data now)
My Question is: how can I call the sortFunction() which is included in my TableViewController in the SortViewController?
This what I have:
TableViewController:
func sortFunction(){
self.data?.sortInPlace({ $0.clicks > $1.clicks })
self.tableView.reloadData()
}
SortViewController:
When the specific sort Button is clicked:
#IBAction func sortBestClicks(sender: AnyObject) {
// how to call the function from TableViewController here??
}
When Done is Clicked:
#IBAction func doneButton(sender: AnyObject) {
self.performSegueWithIdentifier("unwindToStart", sender: self)
}
In TableViewController viewDidLoad add
NSNotificationCenter.defaultCenter().addObserver(self, selector: "methodOfReceivedNotification", name:"NotificationIdentifier", object: nil)
and add a method in TableViewController like
func methodOfReceivedNotification() {
sortFunction()
}
in SortViewController call the method with
NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: nil)
Hope this helps you.
You could also use a delegate protocol.