2

I have 2 view controller.
1. ViewController (VC)
2. WebViewController (WVC)

In VC I click on a button and WVC is shown. After successfully completing all tasks in WVC, I want to show VC and execute a particular function in VC.

Now, Storyboard contains some objects and add to VC using click and drag. Initially, it has some values(not nil). I Click on button, WVC is pushed, After completing all task in WVC, VC is pushed.

Now some values in VC is nil. error,welcome (UILabel, UIView) is nil... And also is want to call a function in VC. How it is possible.?

Code

ViewController.swift

class LoginController:UIViewController,UITextFieldDelegate{
    @IBOutlet weak var password: UITextField!
    @IBOutlet weak var username: UITextField!
    @IBOutlet weak var error: UILabel!
    @IBOutlet weak var welocome: UILabel!

    ......

    @IBAction func BtnClicked(sender: AnyObject) {
     let webViewCnt = self.storyboard!.instantiateViewControllerWithIdentifier("WebViewController") as UIViewController
        self.navigationController?.pushViewController(webViewCnt, animated: true)
    }
    func doSomeProcess(){

    }
}

WebViewController.swift

class WebViewController: UIViewController, UITextFieldDelegate,UIWebViewDelegate {
 override func viewDidLoad() {
    super.viewDidLoad()
    webView.delegate = self

    self.start()
}
 func start(){
      ---- do some process ----
      dispatch_async(dispatch_get_main_queue(), { () -> Void in
        let ViewCont = self.storyboard!.instantiateViewControllerWithIdentifier("LoginController") as UIViewController

        self.navigationController?.pushViewController(ViewCont, animated: true)
        ViewController().doSomeProcess() // call viewcontroller doSomeProcess() function
       }
   })
 }
}
Eldhose Elias
  • 389
  • 1
  • 6
  • 22

3 Answers3

1

Try to pop:

In this start() method just replace a line self.navigationController?.popViewController(animated: true) instead of pushing the ViewController.

func start(){
      ---- do some process ----
      dispatch_async(dispatch_get_main_queue(), { () -> Void in
        let ViewCont = self.storyboard!.instantiateViewControllerWithIdentifier("LoginController") as UIViewController

        self.navigationController?.pushViewController(ViewCont, animated: true)
        ViewController().doSomeProcess() // call viewcontroller doSomeProcess() function
       }
   })
 }

Reason:

When you are pushing to any ViewController, The storyboard will create a new reference of ViewController and the OOP's says every object has its own properties and method so that's why your pushing view controller properties may be nil assume that your username: UITextField! text will be nil due to separate instance of ViewController.

For calling the function of your view-controller you have to implement the delegate if it is not for every time else you may work in viewwillappear.

Salman Ghumsani
  • 3,647
  • 2
  • 21
  • 34
1

Simple your are pushing VC to WVC, So logically after pushing WVC to NavigationController. it added WVC to the top of Navigation Stack. & it it better to pop this WVC from Navigation will automatically show VC with previous values.

use this

ViewController.swift

class LoginController:UIViewController,UITextFieldDelegate{
    @IBOutlet weak var password: UITextField!
    @IBOutlet weak var username: UITextField!
    @IBOutlet weak var error: UILabel!
    @IBOutlet weak var welocome: UILabel!
    var isBackFromWVC = false
    ......

    @IBAction func BtnClicked(sender: AnyObject) {
       let webViewCnt = self.storyboard!.instantiateViewControllerWithIdentifier("WebViewController") as UIViewController
        self.navigationController?.pushViewController(webViewCnt, animated: true)   
       isBackFromWVC = true
    }
    func doSomeProcess(){

    }
    func vieWillAppear(){
      if(isBackFromWVC){
        doSomeProcess()
      }
   }
}

WebViewController.swift

class WebViewController: UIViewController, UITextFieldDelegate,UIWebViewDelegate {
 override func viewDidLoad() {
    super.viewDidLoad()
    webView.delegate = self

    self.start()
 }
 func start(){
      ---- do some process ----
      dispatch_async(dispatch_get_main_queue(), { () -> Void in

         self.navigationController?.popViewController(animated:true)
       }
      })
  }
}
Eldhose Elias
  • 389
  • 1
  • 6
  • 22
Firoj
  • 106
  • 8
0

From my understanding, probably what you want is to dismiss WVC and go back to VC.

in WebViewController's start():

self.navigationController?.popViewController(animated: true)

and after pop, you need to execute doSomeProcess() function. There're several ways to do this and I'll introduce one here.

in ViewController, implement UINavigationControllerDelegate:

func navigationController(_ navigationController: UINavigationController, animationCOntrollerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewCOntroller) -> UIViewControllerAnimatedTransitioning? {
    switch operation {
    case .pop:
        let to = toVC as! ViewController
        to.doSomeProcess()
    default:
        break
    }
    return nil
}

of course you'll need

self.navigationController?.delegate = self

inside VC's viewDidLoad() as well.

sCha
  • 1,454
  • 1
  • 12
  • 22