Reputation: 3270
I want to create my own custom UILabel using swift and I'm running into frame issues when using the init super class.
This is what I had before:
let label = UILabel()
I used to basically use a normal UILabel. Firstly my question is, how is the frame set for this? Because when I step inside the UILabel class it inherits from UIView and the init method inside UIView takes a frame. So how is this frame created?
This then brings me to my own custom UILabel, which I have called TimeLabel. Here is its implementation:
class TimeLabel: UILabel {
var clientName: String?
var time: Time?
init(name:String, time:Time) {
self.clientName = name
self.time = time
super.init(frame: ??)
}
required init?(coder aDecoder: NSCoder) {
super.init(frame:??)
}
}
This now links to the first question, where should I be getting this frame from? I wasn't providing a frame before when calling UILabel? How should I deal with this?
Upvotes: 0
Views: 4712
Reputation: 3464
This is how you setup your class:
Remember to use "convenience" keyword. By using convenience keyword you don't need to add NSCoding protocol inherited by UIVIew.
class TimeLabel: UILabel {
var clientName: String?
var time: Time?
// Use convenience keyword
convenience init(name: String?, time: Time?) {
self.init(frame: CGRect.zero)
self.clientName = name
self.time = time
}
}
This is how you get the width and height based on the content
let timeLabel = TimeLabel(name: "John", time: sometime)
let size = timeLabel.sizeThatFits(CGSize.zero)
// This is the label calculated width and height
let width = size.width
let height = size.height
let timeLabel = TimeLabel(name: "John", time: sometime)
// To active multiline features, set numberOfLines to 0
timeLabel.numberOfLines = 0
let size = timeLabel.sizeThatFits(CGSize(width: putYourWidthHere, height: 0))
// This is the label calculated width and height
let width = size.width
let height = size.height
Upvotes: 5
Reputation: 66224
If you don't want to provide a frame at initialization time, use CGRect.zero
:
class TimeLabel: UILabel {
var clientName: String?
var time: Time?
init(name:String, time:Time) {
self.clientName = name
self.time = time
super.init(frame: CGRect.zero)
}
}
You can always change the frame later, or use auto-layout and the frame will be set for you.
Your init(coder:)
method should only decode your subclass' properties (if you want), and should leave everything else to the superclass:
required init?(coder aDecoder: NSCoder) {
// decode clientName and time if you want
super.init(coder: aDecoder)
}
Upvotes: 1
Reputation: 5331
1) This is how i would initialize a label with frame
UILabel(frame: CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: 100.0 , height: 60.0)))
2) in custom class though you can do this...
override init(frame: CGRect) {
super.init(frame: frame)
}
both are separate things.. did i get you right? ask a question if any doubt
One reference
Upvotes: 0