Swift: Function Called when Back is pressed - swift

I would like to perform some actions when a user presses the "Back" button on my Navigation Controller. Is there a Swift function that is called when this happens?

Try this (copied and pasted from manecosta)
Replacing the button to a custom one as suggested on another answer is possibly not a great idea as you will lose the default behavior and style.
One other option you have is to implement the viewWillDisappear method on the View Controller and check for a property named isMovingFromParentViewController. If that property is true, it means the View Controller is disappearing because it's being removed (popped).
Should look something like:
override func viewWillDisappear(animated : Bool) {
super.viewWillDisappear(animated)
if (self.isMovingFromParentViewController()){
// Your code...
}
}
Here is the link to the other question

override func viewWillDisappear(animated: Bool) {
// Do Your Lines of Code ...
}
Everytime when back button or Done is pressed or a view is popped out this function is called.. you need to override this..

Try to call this
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
if self.isMovingFromParent {
print("isMovingFromParent()") // dismiss for push viewController
}
if self.isBeingDismissed {
print("isBeingDismissed()") // dismiss for modal that doesn't has navigationController
}
if self.navigationController?.isBeingDismissed ?? false {
print("navigationController?.isBeingDismissed()") // dismiss for modal that has navigationController
}
}

Try this:
override func willMoveToParentViewController(parent: UIViewController?) {
if parent == nil {
// Back button Event handler
}
}

Swift 5
"viewWillDisappear" call Every time for forward or backward.
But if you add this check it's call only when back from controller.
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if self.isMovingFromParent {
print("Only back action")
}
}

Related

how can i dismiss a viewcontroller whilst at the same time segue onto a different one

I am currently unable to dismiss a viewcontroller and at the same time make the application move to a different controller without experiencing a few bugs. What my code does currently is when the timer 'secondsRemaining' hits zero it will dismiss the current viewcontroller it is on and will show the previous viewController that is displayed underneath the current viewcontroller being the 'homeScreenViewController'. Because of this it will not call the code- self.performSegue(withIdentifier: "gameScreenToHighscore", sender: self).
Current code:
#objc func updateTimer() {
if secondsRemaining > 0 {
secondsRemaining -= 1
timerLabel.text = "Timer:\(secondsRemaining)"
print(secondsRemaining)
} else {
self.dismiss(animated: true, completion: nil)
self.performSegue(withIdentifier: "gameScreenToHighscore", sender: self)
}
}
I think the best approach is that you handle the navigation in the parent ViewController, You can achieve this by making delegate.
In the ChildViewController:
#protocol ModalVCDelegate {
func navigateToTheSecondVC()
}
class ModalViewController {
weak delegate: ModalVCDelegate!
}
and you should call the delegate method when the timer has done.
delegate?.navigateToTheSecondVC()
And Also in the ParentViewController, you should set the delegate:
childVC.delegate = self
present(childVC, animated: true, completion: nil)
and then:
extension MainViewController: ModalVCDelegate {
func navigateToTheSecondVC {
dismiss(animated: true, completion: {
self.performSegue(withIdentifier: "gameScreenToHighscore", sender: self)
})
}
}

Refreshing tableview data after dismiss() called on another tableview

Setup: table view controller has button (Add) that pops up another view controller with a form. I'm using Realm to store data, so no need to pass data back. However, when I dismiss() the view controller, and return to the table view controller, I cannot get tableView.reloadData() to work.
I have tried viewWillAppear() and viewDidAppear() but neither appear to be in the call stack.
Any ideas where I need to put this?
You need a delegate
let second = ///
second.delegate = self
When you dismiss in 2nd vc
delegate?.refresh()
Probably your second controller is being displayed modally. According to Apple Developer Documentation:
If a view controller is presented by a view controller inside of a popover, this method is not invoked on the presenting view controller after the presented controller is dismissed.
You can solve your problem with a delegate:
protocol ControllerBDelegate {
func willDismiss()
}
class ControllerA {
func open() {
let vc = ControllerB()
vc.delegate = self
self.present(vc, animated: true)
}
}
extension ControllerA : ControllerBDelegate {
func willDismiss() {
self.tableView.reloadData()
}
}
class ControllerB {
weak var delegate: ControllerBDelegate?
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
delegate?.willDismiss()
}
}

How to click a button programmatically?

I have 2 view controllers which should be swapped according to userinput. So, I want to switch the views programatically based on the input I get from a text file.
Algorithm :
if(input == 1)
{
Go to View Controller 1
}
else if(input ==2)
{
Go to View Controller 2
}
Any help on how to click the button programmatically or load that particular viewcontroller with input?
To fire an event programmatically you need to call sendActionsForControlEvent
button.sendActionsForControlEvents(.TouchUpInside)
--
Swift 3
button.sendActions(for: .touchUpInside)
Or you can just put all the logic that you perform when a button gets clicked in a separate method, and call that method from your button's selector method.
#IBAction func someButtonPressed(button: UIButton) {
pushViewControllerOne()
}
#IBAction func someButtonPressed(button: UIButton) {
pushViewControllerTwo()
}
func pushViewControllerOne() {
let viewController = ViewControllerOne(nibName: "ViewControllerOne", bundle: nil)
pushViewController(viewController)
}
func pushViewControllerTwo() {
let viewController = ViewControllerOne(nibName: "ViewControllerTwo", bundle: nil)
pushViewController(viewController)
}
func pushViewController(viewController: UIViewController) {
navigationController?.pushViewController(viewController, animated: true)
}
Then instead of invoking programatically invoking a button press, just call the method pushViewControllerOne() or pushViewControllerTwo()

How to dismiss view in swift? dismissViewControllerAnimated is not doing anything?

I have an issue where dismissViewController method is not actually doing anything. My code is as follows:
import UIKit
class CameraController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
....
#IBAction func dismissPhotoPicker(sender: UIButton!) {
print("in the function")
self.dismissViewControllerAnimated(true, completion: nil)
}
}
No errors are thrown when running, click on the button does trigger the method (I put a print statement in the function)
There are 2 buttons "Back", which calls that method, and another one called "Open Image Picker", which opens the Image Picker.
My storyboard starts with a TabBarViewController, I set up a segue such that when clicking on the "Camera" button, it switches to the "CameraViewController", which is associated with the custom class CameraController (which I've specified in my Storyboard.xib file)
Can you do something like this?
yourView:UIView {
// do something
}
yourMainController:UIViewController {
let view = yourView()
func showView() {
self.view.addSubview(view)
}
func hideView() {
view.removeFromSuperView()
}
}
Try this code:
if self.isBeingPresented() {
// being presented
print("being present, going to dismiss..")
self.dismissViewControllerAnimated(true, completion: nil)
} else if self.isMovingToParentViewController() {
// being pushed
print("being pushed, going to pop..")
if let navController = self.navigationController {
navController.popViewControllerAnimated(true)
}
} else {
// simply showing again because another VC was dismissed
}

Swift: Show UIView when button with segue is clicked

I try to show a UIView when a button is clicked, but it seems that the UI can't get updated, because the button also activates a segue. When I delete the segue, the UI is updated and my UIView is drawn.
Can anyone help me on how to solve this problem?
override func shouldPerformSegueWithIdentifier(identifier: String, sender: AnyObject!) -> Bool {
if identifier == "mySegue" {
if(myLocation == nil) {
/* Rest of code */
return false
}
else {
// These properties need to be set
box.hidden = false
actInd.startAnimating()
return true
}
}
return true
}
#IBAction func startComputing(sender: UIButton) {
//When I put the properties, nothing happens,
//but something like print("Button pressed") does happen.
}
Thanks in advance!
From what I understand, the view is within the view controller window hierarchy, so I'd do this without using segues:
#IBAction func startComputing(sender: UIButton) {
UIView.transitionWithView(self.yourView, duration: 0.5, options:UIViewAnimationOptions.TransitionFlipFromLeft, animations: {
}, completion: nil)
}
This will present your view when the button is clicked. Inside the block you can do the rest like updating UI etc.