I am Copying the same Question asked Before Question. I have tried the solutions given and was not able to solve it since sizetofit was not effective when I
Auto layout only work with edges/sizes of controller, not with controllers content.so its not a good idea to use auto layout to display your label text on top of first line. according to me sizetofit is a best option to do so.
There is an easy solution for cases where the height of a label doesn't need to be constant: put your Label
in a Stack View
. Be sure to add leading and trailing constants to the Stack View
. Here is a screenshot of how to do it in storyboard:
I used @Daniel Golasko's solution and whenever the text inside the UILabel was longer than the UILabel could contain, the text would start moving down instead of staying aligned to top.
I changed this line to make sure the text is aligned properly
[super drawTextInRect:CGRectMake(0, 0, ceilf(CGRectGetWidth(self.frame)),MIN(ceilf(labelStringSize.height), self.frame.size.height))];
use this my class, you can change text alignment
by contentMode
.
supported case: .top, .bottom, .left, .right, .topLeft, .topRight, .bottomLeft, .bottomRight
Swift4
import Foundation
import UIKit
@IBDesignable
class UIAlignedLabel: UILabel {
override func drawText(in rect: CGRect) {
if let text = text as NSString? {
func defaultRect(for maxSize: CGSize) -> CGRect {
let size = text
.boundingRect(
with: maxSize,
options: NSStringDrawingOptions.usesLineFragmentOrigin,
attributes: [
NSAttributedStringKey.font: font
],
context: nil
).size
let rect = CGRect(
origin: .zero,
size: CGSize(
width: min(frame.width, ceil(size.width)),
height: min(frame.height, ceil(size.height))
)
)
return rect
}
switch contentMode {
case .top, .bottom, .left, .right, .topLeft, .topRight, .bottomLeft, .bottomRight:
let maxSize = CGSize(width: frame.width, height: frame.height)
var rect = defaultRect(for: maxSize)
switch contentMode {
case .bottom, .bottomLeft, .bottomRight:
rect.origin.y = frame.height - rect.height
default: break
}
switch contentMode {
case .right, .topRight, .bottomRight:
rect.origin.x = frame.width - rect.width
default: break
}
super.drawText(in: rect)
default:
super.drawText(in: rect)
}
} else {
super.drawText(in: rect)
}
}
}
In the Interface Builder, just make the height <= some value instead of =. This will enable to text to start at the top and expand the height as needed. For example, I have a label with a height proportional to the size of the main view. So my height constraint looks like this: Height Constraint
If you're not restricted by having UILabel of fixed size, instead of aligning the text within a UILabel, simply use ≥ constraint on the given label to change the size of it.
It's the most elegant solution using Auto Layout. Don't forget to set numberOfLines to zero though.