UITextView
iOS Development
Vertical Alignment
Swift Programming
User Interface Design

Center text vertically in a UITextView

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

UITextView does not have a built-in vertical-alignment property, so text naturally starts at the top. If you need a short block of text to sit in the vertical middle, you have to calculate the extra vertical space yourself and apply it as inset or offset. The key is to update that calculation whenever the bounds or content size changes.

Why UITextView Does Not Center Vertically

UITextView is a scroll view with a text container. That means it is designed for top-aligned, scrollable editing, not label-style centering. When the text is shorter than the available height, the unused area remains below the text unless you adjust it.

This is different from UILabel, where visual centering is more straightforward. With UITextView, you usually modify one of two things:

  • 'textContainerInset'
  • 'contentOffset'

Insets are usually the cleaner option.

Simple Approach: Adjust textContainerInset

If the text view has fixed bounds and relatively short content, compute top inset from the difference between visible height and content height.

swift
1import UIKit
2
3func centerTextVertically(_ textView: UITextView) {
4    let fittingHeight = textView.sizeThatFits(
5        CGSize(width: textView.bounds.width, height: .greatestFiniteMagnitude)
6    ).height
7
8    let top = max(0, (textView.bounds.height - fittingHeight) / 2)
9    textView.textContainerInset.top = top
10    textView.textContainerInset.bottom = 0
11}

This works best when the text fits without scrolling. Once the content becomes taller than the view, the top inset should fall back to zero.

Better Reusable Solution: Subclass UITextView

If the text changes often, move the logic into a subclass and recalculate during layout.

swift
1import UIKit
2
3final class VerticallyCenteredTextView: UITextView {
4    override var text: String! {
5        didSet { updateVerticalAlignment() }
6    }
7
8    override var attributedText: NSAttributedString! {
9        didSet { updateVerticalAlignment() }
10    }
11
12    override func layoutSubviews() {
13        super.layoutSubviews()
14        updateVerticalAlignment()
15    }
16
17    private func updateVerticalAlignment() {
18        let fittingHeight = sizeThatFits(
19            CGSize(width: bounds.width, height: .greatestFiniteMagnitude)
20        ).height
21
22        let topInset = max(0, (bounds.height - fittingHeight) / 2)
23        textContainerInset.top = topInset
24    }
25}

This keeps centering logic in one place and survives rotation or auto layout changes.

Alternative: Adjust contentOffset

Another technique is shifting the scroll offset instead of using insets.

swift
1func centerWithContentOffset(_ textView: UITextView) {
2    let topCorrect = max(0, (textView.bounds.height - textView.contentSize.height) / 2)
3    textView.contentOffset = CGPoint(x: 0, y: -topCorrect)
4}

This can work, but it is often less stable for editable text views because content size changes during typing and scrolling behavior can feel odd. Use it only when inset-based layout does not fit the design.

Editable vs Read-Only Behavior

Vertical centering looks good for:

  • placeholders
  • short read-only text
  • quote-style content blocks

It is usually a poor fit for large editable fields. Once the user starts typing several lines, top alignment is more natural and predictable. For editable note fields, center only when content is short, then switch back to top alignment automatically.

Handle Dynamic Type and Rotation

Font size changes and device rotation both affect the fitted height. If you compute the inset once and never recalculate, the text can end up visibly off-center later.

A safe rule is:

  1. Recalculate in layoutSubviews.
  2. Recalculate after text changes.
  3. Recalculate after font changes.

That keeps the visual result stable across common UI changes.

Testing the Result

You should test with:

  • one short line
  • multiple lines that still fit
  • text longer than the view height
  • dynamic type larger sizes

Short manual verification example:

swift
textView.text = "Hello"
centerTextVertically(textView)

Then switch to a longer paragraph and confirm the view falls back to top-oriented behavior rather than clipping or drifting.

Common Pitfalls

  • Expecting UITextView to support vertical alignment the way UILabel does.
  • Applying a fixed top inset without recalculating after layout changes.
  • Centering large editable text where top alignment is better UX.
  • Using contentOffset in a way that fights normal scrolling behavior.
  • Forgetting that dynamic type changes invalidate the original centering math.

Summary

  • 'UITextView needs manual math for vertical centering.'
  • 'textContainerInset is usually cleaner than contentOffset.'
  • A small subclass is the most maintainable approach for dynamic layouts.
  • Recalculate when bounds, text, or font size changes.
  • Use vertical centering mainly for short content, not long-form editing.

Course illustration
Course illustration

All Rights Reserved.