Reputation: 2253
I am trying to create a framework (Login VC) which contains a view controller. I have successfully imported the framework and presented the VC, but the view is not showing. I have a print function in the imported viewDidLoad and it is printing. What am I missing?
Framework VC:
public class LoginVC: UIViewController {
@IBOutlet weak var button: UIButton! {
didSet {
button.addTarget(self, action: #selector(buttonPressed), for: .touchUpInside)
}
}
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override public func viewDidLoad() {
super.viewDidLoad()
print("View Loaded") // Firing
}
@objc func buttonPressed() {
print("hello")
}
}
Framework VC Xib:
This is view debugger when I present the framework VC
-- Update: This is how I am showing the VC ---
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
let homeViewController = LoginVC()
homeViewController.view.backgroundColor = UIColor.white
window!.rootViewController = homeViewController
window!.makeKeyAndVisible()
return true
}
-- Update --
Since many comments relate to the app delegate, I first present a general ViewController which then will present my login framework VC.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
let homeViewController = ViewController()
homeViewController.view.backgroundColor = UIColor.white
window!.rootViewController = homeViewController
window!.makeKeyAndVisible()
return true
}
class ViewController: UIViewController {
@IBOutlet weak var button: UIButton! {
didSet {
button.addTarget(self, action: #selector(presentNext), for: .touchUpInside)
}
}
@objc func presentNext() {
let loginVC = LoginVC()
present(loginVC, animated: true, completion: nil)
}
}
Now, when I present the login framework, all I get is a black screen.
-- Update --
I can change the background color of the view in viewdidLoad, but the xib views are not shown. Why is this?..
Upvotes: 1
Views: 769
Reputation: 2253
Frameworks with xibs connected to viewController require explicit loading from the bundle.
Usually when we create a cocoaTouch UIViewController with xib, this is handled for us. However, when using frameworks, it is not handled.
To solve this, I add load the xib in viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
// Frameworks require loading of the xib to connect xib to view controller
let bundle = Bundle(for: type(of: self))
bundle.loadNibNamed("viewControllerName", owner: self, options: nil)
}
Upvotes: 2
Reputation: 6090
You need to call your presentNext() after the ViewController has actually appeared -- not in viewDidLoad, and not even in viewWillAppear.
Like this:
class ViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
presentNext()
}
@objc func presentNext() {
let loginVC = LoginVC()
present(loginVC, animated: true, completion: nil)
}
}
Here's the working test project:
https://github.com/drewster99/SO_LoginVC
Also, maybe double-check that your ViewController.xib has the IBOutlet actually attached for the button. It's actually got to be that. Everything else looks good.
Here's what I've got:
AppDelegate:
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
let homeViewController = ViewController()
homeViewController.view.backgroundColor = UIColor.white
window!.rootViewController = homeViewController
window!.makeKeyAndVisible()
return true
}
}
ViewController.swift:
import UIKit
import LoginFrameworkThing
class ViewController: UIViewController {
@IBOutlet weak var button: UIButton! {
didSet {
button.addTarget(self, action: #selector(presentNext), for: .touchUpInside)
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
@objc func presentNext() {
print("Presenting next...")
let loginVC = LoginVC()
present(loginVC, animated: true, completion: nil)
}
}
The button is connected in ViewController, and LoginVC (both .xib and .swift) exist in the framework.
I updated the sample project. Check the link.
Upvotes: 1