The default UILabel always centers text vertically.
Often you want to keep your text on top - or bottom of the control.
In my current project I have the following situation:
- Little space (as usual).
- On top a UILabel with 3 lines
- 90% of the time the Top UILabel uses 2 lines or even only 1 line
When there is only one line of text in the Top-Label the things look OK.
With 2 lines I have to much space on top – and too little on bottom. (Looks very nasty).
With 3 lines Top space is OK and bottom is a bit narrow. But this only occurs very seldom.
And it doesn’t look totally bad, since the top space is also small.
The reason for the problem – UILabel always centers the text vertically.
This is just an example – but I often have the situation where I would like to have “a bit more space for exceptional situations”.
As used from windows development I solve such problem by using a label which has place for the extra information – and comes near the next control.
This means a nice looking UI – and if the space is needed it is there.
In this (seldom) situation the distance to the next control is smaller than normally – but this doesn’t occur often.
To come to a point: the real problem is that UILabel always centers text vertically.
To overcome the problem I decided to build my own label control – with a VerticalAlignment property added.
Since I guess that such a situation is more or less common I decided to publish this class.
And because it is really simple – I don’t attach a file, or publish a library somewhere – instead I post the code here.
Snippet created with CBEnhancer public class HLabel :
UILabel {
public enum VerticalAlignments {
Middle = 0,
//the default (what standard UILabels do) Top, Bottom }
#region VerticalAlignment
private VerticalAlignments m_eVerticalAlignment;
public VerticalAlignments VerticalAlignment {
get {
return m_eVerticalAlignment; }
set {
if (m_eVerticalAlignment !=
value) {
m_eVerticalAlignment =
value;
SetNeedsDisplay();
//redraw if value changed }
}
}
#endregion #region construction
public HLabel() { }
public HLabel(
RectangleF rF) :
base(rF) { }
//add other constructors if needed #endregion #region overrides (DrawText, TextRectForBounds)
//normally it uses full size of the control - we change this public override void DrawText(
RectangleF rect) {
RectangleF rErg = TextRectForBounds(rect, Lines);
base.DrawText(rErg);
}
//calculate the rect for text output - depending on VerticalAlignment public override RectangleF TextRectForBounds(
RectangleF rBounds,
int nNumberOfLines) {
RectangleF rCalculated=
base.TextRectForBounds(rBounds, nNumberOfLines);
if (m_eVerticalAlignment !=
VerticalAlignments.Top) {
//no special handling for top if (m_eVerticalAlignment ==
VerticalAlignments.Bottom) {
rBounds.Y += rBounds.Height - rCalculated.Height;
//move down by difference }
else {
//middle == nothing set == somenthing strange ==> act like standard UILabel rBounds.Y += (rBounds.Height - rCalculated.Height) / 2;
}
}
rBounds.Height = rCalculated.Height;
//always the calculated height return (rBounds);
}
#endregion }
The class is really simple. It overrides TextRectForBounds – a method which calculates the rectangle wherein a text should display. In this method we change height and top (Y) of the bounding rectangle depending on VerticalAlignment.
Next we have a property for vertical alignment – where the setter forces a redraw if the value changes.
The property has (of course) an enum for the values.
Last not least we have constructors – that’s it.
Very simple (written in about 5 minutes) – but (at least for me) very usefully.
I hope some of you think also that this class is useful.
Manfred