Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSInvalidArgumentException reason: 'Storyboard doesn't contain a view controller with identifier 'CenterViewController''

Tags:

ios

swift

Error: Failed to instantiate the default view controller for UIMainStoryboardFile 'Main' - perhaps the designated entry point is not set?

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Storyboard (<UIStoryboard: 0x7ff949770c30>) doesn't contain a view controller with identifier 'CenterViewController''

I dont' know what's wrong with my Main Storyboard.I was building slide out navigation panel of my own.

CenterViewController.swift

import UIKit
@objc
protocol CenterViewControllerDelegate {
    optional func toggleLeftPanel()
    optional func collapseSidePanels()
}

class CenterViewController: UIViewController, SideMenuPanelViewControllerDelegate {

//@IBOutlet weak private var testimageView: UIImageView!
@IBOutlet weak private var testLabel:UILabel!

var delegate: CenterViewControllerDelegate?

// MARK: Button actions

@IBAction func MenuTapped(sender: AnyObject) {
    delegate?.toggleLeftPanel?()
}

func localSelected(local: LocalMenus) {
    //imageView.image = animal.image
    testLabel.text = local.title

    delegate?.collapseSidePanels?()
}


/*
// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    // Get the new view controller using segue.destinationViewController.
    // Pass the selected object to the new view controller.
}
*/

}

ContainerViewController.swift

import UIKit
import QuartzCore

enum SideOutState {
    case BothCollapsed
    case LeftPanelExpanded
    case RightPanelExpanded
}

class ContainerViewController: UIViewController, CenterViewControllerDelegate, UIGestureRecognizerDelegate{
    var centerNavigationController: UINavigationController!
    var centerViewController: CenterViewController!

    var currentState: SideOutState = .BothCollapsed {
        didSet {
            let shouldShowShadow = currentState != .BothCollapsed
            showShadowForCenterViewController(shouldShowShadow)
        }
    }

var leftMenuController: SideMenuPanelViewController?

let centerPanelExpandedOffset: CGFloat = 60

override func viewDidLoad() {
    super.viewDidLoad()

    centerViewController = UIStoryboard.centerViewController()
    centerViewController.delegate = self

    // wrap the centerViewController in a navigation controller, so we can push views to it
    // and display bar button items in the navigation bar
    centerNavigationController = UINavigationController(rootViewController: centerViewController)
    view.addSubview(centerNavigationController.view)
    addChildViewController(centerNavigationController)

    centerNavigationController.didMoveToParentViewController(self)

    let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: "handlePanGesture:")
    centerNavigationController.view.addGestureRecognizer(panGestureRecognizer)
}

// MARK: CenterViewController delegate methods

func toggleLeftPanel() {
    let notAlreadyExpanded = (currentState != .LeftPanelExpanded)

    if notAlreadyExpanded {
        addLeftPanelViewController()
    }

    animateLeftPanel(shouldExpand: notAlreadyExpanded)
}

func collapseSidePanels() {
    switch (currentState) {
    case .LeftPanelExpanded:
        toggleLeftPanel()
    default:
        break
    }
}

func addLeftPanelViewController() {
    if (leftMenuController == nil) {
        leftMenuController = UIStoryboard.leftMenuController()
        leftMenuController!.local = LocalMenus.allLocal()

        addChildSidePanelController(leftMenuController!)
    }
}

func addChildSidePanelController(sidePanelController:SideMenuPanelViewController) {

    sidePanelController.delegate = centerViewController

    view.insertSubview(sidePanelController.view, atIndex: 0)

    addChildViewController(sidePanelController)
    sidePanelController.didMoveToParentViewController(self)
}

func animateLeftPanel(#shouldExpand: Bool) {
    if (shouldExpand) {
        currentState = .LeftPanelExpanded

        animateCenterPanelXPosition(targetPosition: CGRectGetWidth(centerNavigationController.view.frame) - centerPanelExpandedOffset)
    } else {
        animateCenterPanelXPosition(targetPosition: 0) { finished in
            self.currentState = .BothCollapsed

            self.leftMenuController!.view.removeFromSuperview()
            self.leftMenuController = nil;
        }
    }
}

func animateCenterPanelXPosition(#targetPosition: CGFloat, completion: ((Bool) -> Void)! = nil) {
    UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: .CurveEaseInOut, animations: {
        self.centerNavigationController.view.frame.origin.x = targetPosition
        }, completion: completion)
}

func showShadowForCenterViewController(shouldShowShadow: Bool) {
    if (shouldShowShadow) {
        centerNavigationController.view.layer.shadowOpacity = 0.8
    } else {
        centerNavigationController.view.layer.shadowOpacity = 0.0
    }
}

// MARK: Gesture recognizer

func handlePanGesture(recognizer: UIPanGestureRecognizer) {
    // we can determine whether the user is revealing the left or right
    // panel by looking at the velocity of the gesture
    let gestureIsDraggingFromLeftToRight = (recognizer.velocityInView(view).x > 0)

    switch(recognizer.state) {
    case .Began:
        if (currentState == .BothCollapsed) {
            // If the user starts panning, and neither panel is visible
            // then show the correct panel based on the pan direction

            if (gestureIsDraggingFromLeftToRight) {
                addLeftPanelViewController()
            }

            showShadowForCenterViewController(true)
        }
    case .Changed:
        // If the user is already panning, translate the center view controller's
        // view by the amount that the user has panned
        recognizer.view!.center.x = recognizer.view!.center.x + recognizer.translationInView(view).x
        recognizer.setTranslation(CGPointZero, inView: view)
    case .Ended:
        // When the pan ends, check whether the left or right view controller is visible
        if (leftMenuController != nil) {
            // animate the side panel open or closed based on whether the view has moved more or less than halfway
            let hasMovedGreaterThanHalfway = recognizer.view!.center.x > view.bounds.size.width
            animateLeftPanel(shouldExpand: hasMovedGreaterThanHalfway)
        }
    default:
        break
    }
}

}

private extension UIStoryboard {
    class func mainStoryboard() -> UIStoryboard {
        return UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
    }

    class func leftMenuController() -> SideMenuPanelViewController? {
        return mainStoryboard().instantiateViewControllerWithIdentifier("SideMenuPanelViewController") as? SideMenuPanelViewController
    }

class func centerViewController() -> CenterViewController? {
    return mainStoryboard().instantiateViewControllerWithIdentifier("CenterViewController") as? CenterViewController
}

}
like image 411
Thiha Aung Avatar asked Jan 08 '15 05:01

Thiha Aung


People also ask

How do I set the identifier for Viewcontroller in storyboard?

Step 1: Set a Storyboard IDIn the Storyboard, select the view controller that you want to instantiate in code. Make sure the yellow circle is highlighted, and click on the Identity Inspector. Set the custom class as well as the field called "Storyboard ID". You can use the class name as the Storyboard ID.

How to open view controller Scene in Xcode?

Open Main. storyboard, select View Controller Scene, and drag a pop-up button into the view. You'll use this pop-up button to display the list of products. Set its position using auto layout.

What is UIStoryboard?

A UIStoryboard object manages archived versions of your app's view controllers. At design time, you configure the content of your view controllers visually, and Xcode saves the data needed to recreate that interface in a storyboard file in your app's bundle.

What is instantiate view controller?

instantiateViewController(withIdentifier:)Creates the view controller with the specified identifier and initializes it with the data from the storyboard.


2 Answers

Very simple.

In your main storyboard, you have no ViewController with a Storyboard ID "CenterViewController"

Look here: https://stackoverflow.com/a/11604827/3324388

like image 59
Aggressor Avatar answered Oct 27 '22 22:10

Aggressor


Short answer from Xcode 8.0 onwards,

Go to the Main.storyboard select the target ViewController, press Command+option+3 to display the attributes

  • Fill the StoryBoard ID input field
  • Check the Use Storyboard ID checkbox

enter image description here

I know this could be found on the duplicated referred answer but you need to read, try and error etc.

like image 23
Jaime Agudo Avatar answered Oct 28 '22 00:10

Jaime Agudo