1
votes

I have a MainViewController.swift and it is connected to a Xib File (called MainViewController). The MainViewController is connected to a MenuViewController.swift and its Xib(called MenuViewController). The MainViewController calls the MenuViewContoller using the following code,

override func viewDidLoad() {
    super.viewDidLoad()
    ...
    menuBtn.addTarget(self, action: #selector(callMenuModal), forControlEvents: .TouchUpInside)
    ....

}
func callMenuModal() {
    let menuVC = MenuViewController()
    menuVC.delegate = self
    menuVC.modalPresentationStyle = .OverCurrentContext
    presentViewController(menuVC, animated: false, completion: nil)
}
.......
func backFromMenu() {
    self.dismissViewControllerAnimated(true, completion: nil)
    }
...
...

My friends have made a story board with a lot of Segues and ViewControllers.

I have to now load my .xib file and its corresponding view controller when a button is pressed from a ViewController on the story board. I have looked high and low for a solution and could not find one.

Previously I called my xib directly from the AppDelegate so I didn't have to do any thing. I had only one view controller in the story board and an app delegate for the whole app, the code I used in the delegate is as given below,

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?


func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    window = UIWindow(frame: UIScreen.mainScreen().bounds)

    let mainViewController = MainViewController(nibName: "MainViewController", bundle: nil)

    window?.rootViewController = mainViewController
    window?.makeKeyAndVisible()
    return true        
}
........rest of app delegate....

But I don't know how to load that xib file, from a different view controller in the storyboard or a button press(IBAction) from a ViewController.

4
If you cannot do this simple task, then you need to read and understand more basic tutorials Apple provides.Jeff

4 Answers

3
votes

You can't directly segue to your MainViewController from the storyboard. But you can load it and display it, just like you did your app delegate.

How do you want to display MainViewController? Push it onto a navigation stack, present it modally, something else? I'm going to assume you're using a UINavigationController and you want to push it onto the stack.

In your friend's UIViewController class, add a method to load and present your MainViewController:

func presentMainViewController() {
    let mainVC = MainViewController(nibName:"MainViewController", bundle:nil)
    self.navigationController.pushViewController(mainVC, true);
    // you could present it another way, such as:
    // self.presentViewController(mainVC, true, nil)
    // to present it as a modal
}
2
votes

As a class variable assign this:

var nibName: NibViewClass?

Assign it to the corresponding class made for the nib.

Inside the view controller wherever you want to load the nib, call

nibName = NSBundle.mainBundle().loadNibNamed("NibView", owner: self, options: nil) as? NibViewClass

Make sure that the "NibView" == the name of the Nib UI file. Then you need to add it as a subview like so:

if nibName != nil {
    self.view.addsubview(nibName!)

    //add this line to make it appear where you want it.
    nibName.frame = CGRectMake(xPosition, yPositionOffScreen, nibWidth, nibHeight)
}

Now this will do most of the work for you, but I would recommend animating it as well. There are a few different ways to do so, but one I often use is like so:

UIView.animateWithDuration(0.7, delay: 1.0, options: .CurveEaseIn, animations: {
        nibName.frame.origin.y = yPositionOnScreen
  }, completion: { finished in
        //code to run after nib finishes movement
  })

At any point after you assign the nibName to it's corresponding class, you can assign its local variables from inside your viewController. You could also choose to animate the nib in with x positions if preferred. I would use the same function with the y values reversed to send it back offscreen when done with it.

1
votes

Solved it...it was right in front of my eyes, guess i had to ask the question to write the answer myself, haha, I'm so smart, i added this code to the view controller from the story board and it works like a charm.

import UIKit

class ViewController: UIViewController, communicationControllerM {

    @IBOutlet weak var Btn: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()

        Btn.addTarget(self, action: #selector(callMenuModal), forControlEvents: .TouchUpInside)
    }

    func callMenuModal() {
        let mainVC = MainViewController()
        mainVC.delegate = self
        mainVC.modalPresentationStyle = .OverCurrentContext
        presentViewController(mainVC, animated: false, completion: nil)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func backFromM() {
        self.dismissViewControllerAnimated(true, completion: nil)
    }
}

in my xib view controller i added a return action

playBtn.addTarget(self, action: #selector(goBackToMainVC), forControlEvents: .TouchUpInside)
self.delegate?.backFromM()

Thanks guys!!

0
votes

You load a view controller and its associated nib file exactly the way you are already doing it in your code:

let mainViewController = MainViewController(nibName: "MainViewController", bundle: nil)

That instantiates the view controller, and when you present or push to it, the view will be loaded from the nib and will be placed into the interface.