UILabel with VerticalAlignment

by ManniAT 17. January 2010 18:37
Technorati-Tags: ,,

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:

  1. Little space (as usual).
  2. On top a UILabel with 3 lines
  3. 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

Tags: , ,

iPhone | MonoTouch

Powered by BlogEngine.NET 1.5.0.7

RecentPosts