UIKit
UITextView
iOS Development
Text Styling
Apple Developer

UITextView style is being reset after setting text property

Master System Design with Codemia

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

Introduction

If a UITextView loses formatting after you assign to text, that is expected UIKit behavior. The text property represents plain text, so setting it replaces the current contents without preserving attributes such as fonts, colors, paragraph styles, or links.

When styling matters, use attributedText or edit the text view's textStorage. The correct fix depends on whether you want a single uniform style or rich formatting on specific ranges.

Why Setting text Resets the Style

A UITextView has two related but different models:

  • 'text for plain text'
  • 'attributedText for rich text with attributes attached to ranges'

When you write:

swift
textView.text = "Updated content"

UIKit builds new plain content. It does not know how to preserve prior attribute runs because the new value is just a String.

That is why partial styling disappears. The old attributed content has been replaced.

Use attributedText for Styled Content

If the content needs formatting, build an attributed string and assign that instead.

swift
1import UIKit
2
3let textView = UITextView(frame: .zero)
4
5let styled = NSMutableAttributedString(string: "Important update")
6styled.addAttributes([
7    .font: UIFont.boldSystemFont(ofSize: 18),
8    .foregroundColor: UIColor.systemRed
9], range: NSRange(location: 0, length: styled.length))
10
11textView.attributedText = styled

This is the direct replacement for code that wrongly relied on text while expecting style to survive.

Reapply a Uniform Base Style

Sometimes you do not need complex rich text. You just want the whole text view to keep one font and one color whenever the string changes. In that case, rebuild attributedText with a base attribute set.

swift
1import UIKit
2
3func replaceTextKeepingStyle(_ newText: String, in textView: UITextView) {
4    let font = textView.font ?? UIFont.systemFont(ofSize: 16)
5    let color = textView.textColor ?? .label
6
7    textView.attributedText = NSAttributedString(
8        string: newText,
9        attributes: [
10            .font: font,
11            .foregroundColor: color
12        ]
13    )
14}

This works well when the view has one consistent style rather than many styled ranges.

Edit textStorage for Rich-Text Updates

If only part of the content changes, editing textStorage is often better than rebuilding the entire attributed string manually.

swift
1import UIKit
2
3let textView = UITextView(frame: .zero)
4textView.attributedText = NSAttributedString(
5    string: "Status: Pending",
6    attributes: [.font: UIFont.systemFont(ofSize: 16)]
7)
8
9textView.textStorage.beginEditing()
10textView.textStorage.replaceCharacters(in: NSRange(location: 8, length: 7), with: "Ready")
11textView.textStorage.addAttributes([
12    .foregroundColor: UIColor.systemGreen,
13    .font: UIFont.boldSystemFont(ofSize: 16)
14], range: NSRange(location: 8, length: 5))
15textView.textStorage.endEditing()

That approach is useful when only certain words need styling changes.

Do Not Forget typingAttributes

If the text view is editable, new user input uses typingAttributes, not automatically whatever you last assigned elsewhere.

swift
1textView.typingAttributes = [
2    .font: UIFont.systemFont(ofSize: 16),
3    .foregroundColor: UIColor.label
4]

Without this, the view may look correct after programmatic replacement but switch to an unexpected style when the user starts typing.

Preserve Selection in Editable Views

Replacing the entire contents can move the cursor or clear the selection. If the text view is interactive, save and restore selectedRange around the update.

swift
let selectedRange = textView.selectedRange
replaceTextKeepingStyle("New value", in: textView)
textView.selectedRange = NSRange(location: min(selectedRange.location, textView.text.count), length: 0)

That small detail matters in editors, forms, and chat inputs where cursor jumps feel broken.

Common Pitfalls

The main mistake is setting attributedText and then later overwriting it with text, which removes the styling again. Another is assuming font and textColor are enough to restore rich-text ranges; they only define a default appearance. Developers also forget typingAttributes in editable text views, so user-entered characters use the wrong style. Finally, replacing the whole text without restoring selection can make the control feel glitchy even if the visual formatting is correct.

Summary

  • Setting text resets styling because it replaces rich text with plain text.
  • Use attributedText when formatting must survive updates.
  • For uniform styling, rebuild an attributed string with a base attribute set.
  • For partial rich-text edits, work through textStorage.
  • In editable views, also manage typingAttributes and selection state.

Course illustration
Course illustration

All Rights Reserved.