jon_na_fun
jon_na_fun

Reputation: 1223

ViewController loading twice

I'm using a combination of objective C and swift 3.

In my mainView (Objective C) I have the following

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Storyboard" bundle:[NSBundle mainBundle]];
    CourseViewController *courseView = (CourseViewController*)[storyboard instantiateViewControllerWithIdentifier:@"courseView"];
    [self.navigationController pushViewController:courseView animated:YES];

In my storyboard, my mainView will Show a Navigation Controller that's rootView to the swift 3 view.

In the swift 3 view controller I have the following and the loadView and viewDidLoad gets called twice

override func loadView() {
    webView = WKWebView()

    //If you want to implement the delegate
    webView?.navigationDelegate = self

    view = webView
}

override func viewDidLoad() {
    super.viewDidLoad()
    let temp: CGRect = UIScreen.main.bounds
    screenSize = temp
    let url = URL(string: kcourseURL)
    let req = URLRequest(url: url!)
    webView.allowsBackForwardNavigationGestures = true
    webView.load(req)
    //webView.frame = CGRect(x:0, y:navBarHeight, width:Int(screenSize.width), height:Int(screenSize.height))

    webView.addObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress), options: .new, context: nil)

    self.setBarButton()


}

Any suggestion on why it's being called twice?

Also, I'm trying to dismiss this view to go back to the mainView but it doesn't get called if I use a navigation Controller on the swift 3 view. I've tried the following. Do I need to use a segue unwind to go back to the mainView?

        self.dismiss(animated: true, completion: nil)

    _ = self.navigationController?.popToRootViewController(animated: true)

Upvotes: 1

Views: 3071

Answers (2)

Anand Nimje
Anand Nimje

Reputation: 6251

If you using in your application navigation controller then here one thing I need to clear here if you are using Segue for navigation then no need to call the same view again here with the help of code choose only one process here. Navigation will depend on you which type you want like push, show, present modally and present as popover.

after that need to use only one line for back to view or back to root view: -

 self.dismiss(animated: true, completion: nil)

OR

_ = self.navigationController?.popViewController(animated: true)

OR
for back Rootview

_ = self.navigationController?.popToRootViewController(animated: true)

For navigation, one StoryBoard to another: -

Objective-C

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
SecondViewController *second = (SecondViewController *)[storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
[self.navigationController pushViewController:second animated:YES];

Swift 3

let storyboard = UIStoryboard(name: "Customer", bundle: nil)
let secondVC =   storyboard.instantiateViewController(withIdentifier: "SecondVC") as! SecondVC
self.navigationController!.pushViewController(secondVC, animated: true)

And Try with Segue

First need to take storyBoard reference then add storyBoardname then add inside Referenced Id as your ViewController's StoryBoard ID.

add Storyboard reference

and also confirm your destination controller's Storyboard ID

View Controller's StoryBoard ID

and Finally PerformSegue with data segue identifier: -

 let segueIdentifier = "fourthView"

 //MARK: - Navigation
  override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == segueIdentifier {
          let controller = segue.destination as! FourthVC
          //Passing Values here
          controller.promoViewModel =  promotionModel[0]
        }
    }

Output will be like below image no need to do any extra things: -

OutPut View

Upvotes: 3

aircraft
aircraft

Reputation: 26896

Chech if where you called the loadView() method, because your code is not all post, if is:

You should not call loadView() directly, accoring to apple's doc

You should never call this method directly. The view controller calls this method when its view property is requested but is currently nil. This method loads or creates a view and assigns it to the view property.

If the view controller has an associated nib file, this method loads the view from the nib file. A view controller has an associated nib file if the nibName property returns a non-nil value, which occurs if the view controller was instantiated from a storyboard, if you explicitly assigned it a nib file using the init(nibName:bundle:) method, or if iOS finds a nib file in the app bundle with a name based on the view controller's class name. If the view controller does not have an associated nib file, this method creates a plain UIView object instead.

This is where subclasses should create their custom view hierarchy if they aren't using a nib. Should never be called directly.

No matter you load view for Xib or create view by yourself, viewDidLoad will always be invoked after the view be loaded.

Take your code below:

webView = WKWebView()

//If you want to implement the delegate
webView?.navigationDelegate = self

view = webView

from loadView() to viewDidLoad(), and delete the loadView() method.


Edit - 1

I have write a demo for testing your mixed project, and I find its not because of loadView(), I tried use perform segue and use navigationController push, did not work, so my answer is not fit you, I am find why there is the issue in the mixed demo, strange.

Upvotes: 0

Related Questions