Home>

I am trying to create an app with only code without using Storyboard, xib.
When launching the app, the screen will be black.
I would appreciate it if you could tell me how to solve this problem.

Error message

Create a iOS app UI with code-only without Storyboard
I tried using the source code of this article as it was, but when I started the app, it turned black.
It was displayed in the debug area as follows.

NoStoryBoard [15434: 452943] [WindowScene] Failed to instantiate the default view controller for UIMainStoryboardFile 'Main'-perhaps the designated entry point is not set?

I think it's because it's not working properly in the RootviewController settings, but I don't know how to fix it.
I hope you can lend me your wisdom.

Source code
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    private (set) lazy var viewController = ViewController ()
    func application (_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?)->Bool {
        self.window = UIWindow (frame: UIScreen.main.bounds)
        self.window? .makeKeyAndVisible ()
        self.window? .rootViewController = viewController
        return true
    }
    func application (_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions)->UISceneConfiguration {
        return UISceneConfiguration (name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }
    func application (_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
    }
}
import UIKit
class ViewController: UIViewController {
    override func viewDidLoad () {
        super.viewDidLoad ()
        // Do any additional setup after loading the view.
        let mainView = MainView (frame: self.view.bounds)
        mainView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        self.view.addSubview (mainView)
    }
}
import UIKit
class MainView: UIView {
    let mainLabel: UILabel
    override init (frame: CGRect) {
        self.mainLabel = UILabel ()
        self.mainLabel.text = "Hello World!"
        self.mainLabel.textAlignment = .center
        super.init (frame: frame)
        self.backgroundColor = .white
        self.addSubview (mainLabel)
    }
    required init? (coder: NSCoder) {
        fatalError ("init (coder :) has not been implemented")
    }
    override func layoutSubviews () {
        super.layoutSubviews ()
        let labelSize = self.mainLabel.sizeThatFits (self.bounds.size)
        let x = (self.bounds.width-labelSize.width)/2
        let y = (self.bounds.height-labelSize.height)/2
        let labelOrigin = CGPoint (x: x, y: y)
        self.mainLabel.frame = CGRect (origin: labelOrigin, size: labelSize)
    }
}
  • Answer # 1

    Since iOS13 wants to include a mechanism called SceneDelegate, it seems that it is no longer displayed in the old way of writing.

    How to generate Window and ViewController in code has also been mentioned below, so why not take a look?

    Reference:
    App launch sequence around iOS13 SceneDelegate
    https://qiita.com/omochimetaru/items/31df103ef98a9d84ae6b

  • Answer # 2

    This question has been resolved.
    As you can see in the answer, when deleting the Storyboard and creating UI with code, it seems to use SceneDelegate instead of AppDelegate.
    Write the code below.
    It is assumed that the ViewController and MainView described in the question part remain the same, and AppDelegate is the default state.

    // Omitted
    var window: UIWindow?
        let viewController = ViewController ()
        func scene (_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
            // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene` scene`.
            // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
            // This delegate does not imply the connecting scene or session are new (see `application: configurationForConnectingSceneSession` instead).
            guard let _ = (scene as? UIWindowScene) else {return}
            if let windowScene = scene as? UIWindowScene {
                let window = UIWindow (windowScene: windowScene)
                window.rootViewController = ViewController (nibName: nil, bundle: nil)
                self.window = window
                window.makeKeyAndVisible ()
            }
        }
    // omitted


    Also, it seems necessary to delete StoryboardName in Info of TARGETS.

    By doing this, the label can be displayed on the screen as follows.

Related articles