Reputation: 434
I set some global variables equal to parameters of a class after it's instantiation. The class is defined as so:
import Foundation
import UIKit
class LogIn : UIViewController{
var test:Int = 1
@IBOutlet var login_icon: UIImageView!
@IBOutlet var username_field: UITextField!
@IBOutlet var password_field: UITextField!
@IBOutlet var login_button: UIButton!
@IBOutlet var createaccount_button: UIButton!
}
The global variables are instantiated as so (within a viewDidAppear method):
func showLoginView(){
self.startup_animation.image = self.seq_6
let login_view = LogIn()
self.login_icon = login_view.login_icon.image //Doesnt work
self.username_field = login_view.username_field //Doesnt work
self.password_field = login_view.password_field //Doesnt work
self.login_button = login_view.login_button //Doesnt work
self.createaccount_button = login_view.createaccount_button //Doesnt work
self.int_testval = login_view.test //Works
}
All IBOutlets-connected variables after instantiation are nil values, but var test is instantiated fine. Why is this?
Thanks!
Additional Context The showLoginView function is called with the viewDidAppear function. The whole class looks like so:
class StartupViewController: UIViewController {
var images: [UIImage]!
var animatedImage: UIImage!
@IBOutlet var startup_animation: UIImageView!
@IBOutlet var startup_text: UIImageView!
var login_icon: UIImage!
var username_field: UITextField!
var password_field: UITextField!
var login_button: UIButton!
var createaccount_button: UIButton!
var seq_1 : UIImage!
var seq_2 : UIImage!
var seq_3 : UIImage!
var seq_4 : UIImage!
var seq_5 : UIImage!
var seq_6 : UIImage!
var seq_7 : UIImage!
var seq_8 : UIImage!
var rec_1 : UIImage!
var rec_2 : UIImage!
var rec_3 : UIImage!
var rec_4 : UIImage!
var rec_5 : UIImage!
var rec_6 : UIImage!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
seq_1 = UIImage(named: "Eceipt_seq1")
seq_2 = UIImage(named: "Eceipt_seq2")
seq_3 = UIImage(named: "Eceipt_seq3")
seq_4 = UIImage(named: "Eceipt_seq4")
seq_5 = UIImage(named: "Eceipt_seq5")
seq_6 = UIImage(named: "Eceipt_seq6")
seq_7 = UIImage(named: "Eceipt_seq7")
seq_8 = UIImage(named: "Eceipt_seq8")
images = [seq_1 ,seq_2, seq_3, seq_4, seq_5, seq_6, seq_7, seq_8]
animatedImage = UIImage.animatedImage(with: images, duration: 0.8)
startup_animation.image = animatedImage
let transition_text = UIImage(named: "Eceipt_logo")
UIView.transition(with: self.startup_text, duration: 3.0, options: .transitionCrossDissolve,
animations: {
self.startup_text.image = transition_text
},
completion: { (finished: Bool) -> () in
self.showLoginView()
})
}
func showLoginView(){
self.startup_animation.image = self.seq_6
let login_view = LogIn()
self.login_icon = login_view.login_icon.image
self.username_field = login_view.username_field
self.password_field = login_view.password_field
self.login_button = login_view.login_button
self.createaccount_button = login_view.createaccount_button
}
Upvotes: 0
Views: 376
Reputation: 4226
I think the problem is that you're instantiating the LogIn
view controller by doing let login_view = LogIn()
. When you instantiate a view controller with its empty initializer, every IBOutlet
will be nil because the view controller is not "taken" from a storyboard (or a xib). If you want to use iboutles you must instantiate the view controller from a storyboard or from a xib; in your case (with the storyboard), you should instantiate it by doing:
let storyboard = UIStoryboard(name: "Main", bundle: nil) // name is the filename of the storyboard that contains the vc
let vc = storyboard.instantiateViewController(withIdentifier: "LogIn") as! LogIn // you can cast to have the exact view controller type
present(vc, animated: true, completion: nil)
Make sure that the view controller in your storyboard has the identifier "LogIn".
Upvotes: 1
Reputation: 271410
I think you are misunderstanding the use of @IBOutlet
.
@IBOutlet
just means that it is an outlet of a view or some other object in the xib or storyboard file.
Your views are nil
not because they are outlets, but because they are implicitly unwrapped optionals, which is nil
if you don't give it a value.
test
is not nil, because 1) it is not an optional type and 2) it has a value of 1
.
I suggest you put the @IBOutlet
s in a UIViewController
or UIView
subclass and connect the appropriate views from the storyboard/xib file to it. This way, they will be initialised by the time the viewDidLoad
method or awakeFromNib
method is called.
EDIT:
It seems like that you already control+dragged the views to the LogIn
class. In that case, check if the circles to the left of the outlets are filled. If they are, that means they are properly connected. You just need to wait until awakeFromNib
gets called. If they are not, try connecting them again. Alternatively, just connect all your outlets directly to the view controller, which saves you lots of trouble.
EDIT 2:
Now that I understand what you are trying to do, here is what you should do. You just seems to want to present the LogIn
VC. So instead of assigning every view to self
, properly present it with the present
method.
let vc = UIStoryboard.main!.instantiateViewController(withIdentifier: "Login")
present(vc, animated: true, completion: nil)
Remember to give your login VC in the storyboard a Storyboard ID of "Login".
Upvotes: 1