iOS: Vertical aligning text in a UITextView

The default and expected behavior of a UITextView (multi-line text) out of the box in iOS is to align the text top left in it’s container. That works well most of the time. However I recently had need to either center the text vertically within the control or have all the text align to the bottom of the control.

You can add an observer to the control and when it’s content size changes (text is set), fire a method. The method can then handle how the text is actually positioned in the control. If it doesn’t make sense to do the alignment, it will default to the normal behavior of the control (top vertical alignment).

Here we go:

- (void) viewDidLoad {
   [textField addObserver:self forKeyPath:@"contentSize" options:(NSKeyValueObservingOptionNew) context:NULL];
   [super viewDidLoad];
}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
   UITextView *tv = object;
   //Center vertical alignment
   //CGFloat topCorrect = ([tv bounds].size.height - [tv contentSize].height * [tv zoomScale])/2.0;
   //topCorrect = ( topCorrect < 0.0 ? 0.0 : topCorrect );
   //tv.contentOffset = (CGPoint){.x = 0, .y = -topCorrect};

   //Bottom vertical alignment
   CGFloat topCorrect = ([tv bounds].size.height - [tv contentSize].height);
    topCorrect = (topCorrect <0.0 ? 0.0 : topCorrect);
    tv.contentOffset = (CGPoint){.x = 0, .y = -topCorrect};
}

You can decide which you’d like to use, or flush the method out to take an argument for which type of vertical alignment you’d like to use. This works quite well and it would have been nice if the properties were built into the control to begin with.

If you can use it, enjoy.

Related Posts Plugin for WordPress, Blogger...

8 thoughts on “iOS: Vertical aligning text in a UITextView

  1. Rafael Sanches

    Great hack.

    How do you solve the contentOffset configuration going back to normal when the view that holds this UITextView is refreshed? For example, when it’s inside a tabbar and you switch between tab bars? In my case they get back to the TOP and not to the center.

    thanks
    rafa

    Reply
  2. Jose

    Rafael… I had the same issue. I corrected it by using the contentInsert property instead of the contentOffset. I suspect that iOS doesn’t like to have a negative offset. Apart from that this is a great solution.

    Reply
  3. Dave

    This code works really well. However, when is the right time to remove the observer? I am getting debug output informing me that observation info was leaked. I tried removing the observer in ViewDidUnload but I still get the message.

    Reply
  4. Pingback: [BLOCKED BY STBV] UITextView – align text vertically | Tools, Tips, Tutorials

Leave a Reply

Your email address will not be published. Required fields are marked *


four × 1 =

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>