var label: UILabel!
is declaring that you have a UILabel variable that may be empty (Optional), but you can access it pretending as if it will not - usually that means it would be an IBOutlet that would be set by the interface storyboard on load, before you tried to use the label.
var label = UILabel()
is declaring that you have a label that will always hold a label, and can never be nil. It is ALSO creating an instance of a UILabel when a class instance is created, even though you say you assign a different label to the variable in viewDidLoad()
There's no difference in access, but it does mean no matter when you use that variable it will hold a real value and not be nil.
They both are variables of type UILabel
.
I'm not sure why you could not not set the variable to a new UILabel
using the CGRect
constructor, that should be possible. Perhaps at one point you had said let label = UILabel()
, which would mean it was a fixed variable that could not hold a new value - so all you could do was alter the frame of the variable that exists already.
The best approach for something like what you are doing is to declare the variable an Optional:
var label : UILabel?
Which makes it an true Optional, and makes sure that you do not accidentally write code that accesses the variable badly if it's never been set, or sets a value to your first label before you assign the "real" UILabel in your viewDidLoad
method. Accessing is a little different, but not much harder - to set text you just use the "?" syntax to optionally call the property if the instance has been set:
label?.text = "fred"