UITextView: что это, многострочный ввод и принцип работы

Автор: IT Sectr Опубликовано: 2026-07-07 Время чтения: 8 мин

UITextView — это многострочный текстовый компонент UIKit, наследующий UIScrollView и поддерживающий редактирование атрибутированного текста с встраиванием ссылок и изображений. По документации Apple Developer (2025), UITextView предоставляет UITextViewDelegate с колбэками textViewDidChange, shouldInteractWithURL и shouldInteractWithTextAttachment для обработки взаимодействий. В отличие от UITextField, UITextView поддерживает прокрутку, текстовые стили через typingAttributes и dataDetectorTypes для автоопределения ссылок, адресов и дат. Это основной компонент для отображения контента и ввода многострочного текста в iOS приложениях.

Главное

  • UITextView — многострочное текстовое поле UIKit, наследник UIScrollView с поддержкой редактирования
  • NSAttributedString — поддержка атрибутированного текста: шрифты, цвета, межстрочные интервалы, ссылки
  • UITextViewDelegate — управление через textViewDidChange, shouldInteractWithURL, didBeginEditing
  • Data Detector Types — автоопределение ссылок, адресов, дат, телефонных номеров в тексте
  • Text Container — система textContainer, exclusionPaths и lineFragmentPadding для кастомной вёрстки

Что такое UITextView

UITextView — это компонент UIKit, предназначенный для отображения и редактирования многострочного текста. В отличие от UILabel, UITextView поддерживает выделение текста, редактирование, прокрутку при превышении размеров и атрибутированный текст. Будучи наследником UIScrollView, UITextView автоматически включает вертикальную и горизонтальную прокрутку при превышении контента — это настраивается через isScrollEnabled. Класс поддерживает редактирование через свойство isEditable: установите false для read-only режима просмотра. UITextView работает с NSLayoutManager через систему TextKit: NSTextStorage (хранение атрибутированного текста) → NSLayoutManager (разметка строк) → NSTextContainer (геометрия области текста). Эта архитектура позволяет создавать кастомную вёрстку с обтеканием изображений, много-колоночный текст и сложные текстовые макеты. UITextView используется для отображения статей, описаний, логов, комментариев и любых многострочных текстов в iOS.

UITextView vs UITextField: ключевые отличия

Разница между UITextView и UITextField выходит далеко за рамки количества строк. UITextField — однострочный UIControl с поддержкой placeholder, left/right view и clear button. UITextView — многострочный UIScrollView с полноценной системой TextKit для атрибутированного текста. UITextField не поддерживает NSAttributedString на уровне отображения (только через attributedText с ограничениями), UITextView обрабатывает NSAttributedString полностью с разными шрифтами, параграф-стайлами и встроенными изображениями. UITextField имеет встроенную кнопку очистки (clearButtonMode), UITextView её не имеет — требуется кастомная реализация. UITextField автоматически меняет свой размер под контент (intrinsicContentSize), UITextView требует ручного управления высотой через contentSize наблюдение или Auto Layout constraint. UITextView поддерживает dataDetectorTypes (автоопределение ссылок), UITextField поддерживает его с iOS 16+. Для ввода многострочного текста (комментарии, заметки, сообщения) выбирайте UITextView. Для полей формы (имя, email, пароль) используйте UITextField.

ВозможностьUITextViewUITextField
СтрокиМногострочныйОднострочный
PlaceholderНет (кастомный)Встроенный
Атрибуты текстаПолный NSAttributedStringОграниченный
Data DetectorsПолная поддержкаiOS 16+
Изображения inlineЧерез NSTextAttachmentНе поддерживается
ПрокруткаВстроенная (UIScrollView)Нет
Left/Right ViewНетВстроенные

NSAttributedString и форматирование текста

NSAttributedString — это фундаментальная возможность UITextView, отличающая его от UITextField и UILabel. Атрибутированная строка позволяет задавать разные шрифты, цвета, межстрочные интервалы, выравнивание и ссылки в рамках одного текста. Свойства: textView.attributedText = attributedString. Ключевые атрибуты NSAttributedString.Key: font (.systemFont, .boldSystemFont, кастомный UIFont), foregroundColor, backgroundColor, paragraphStyle (NSMutableParagraphStyle с lineSpacing, alignment, lineBreakMode), link (URL для интерактивных ссылок), underlineStyle, strikethroughStyle, shadow, baselineOffset, kern (межбуквенный интервал). Для создания attributedString используйте init(string:, attributes:) или NSMutableAttributedString для добавления атрибутов к разным диапазонам. UITextView автоматически отображает ссылки (link attribute) как интерактивные — при нажатии вызывается делегатный метод shouldInteractWithURL. Для сброса атрибутов для нового ввода используйте typingAttributes.

swift
import UIKit

let textView = UITextView()
textView.isEditable = false
textView.isScrollEnabled = true
textView.dataDetectorTypes = [.link, .phoneNumber]

let attributedString = NSMutableAttributedString(
    string: "Visit our website or call +1-800-555-0199"
)
attributedString.addAttributes([
    .font: UIFont.systemFont(ofSize: 16),
    .foregroundColor: UIColor.label,
], range: NSRange(location: 0, length: 11))

let linkRange = (attributedString.string as NSString)
    .range(of: "website")
attributedString.addAttributes([
    .link: URL(string: "https://example.com")!,
    .foregroundColor: UIColor.systemBlue,
], range: linkRange)

textView.attributedText = attributedString

Делегат UITextViewDelegate и обработка ссылок

UITextViewDelegate — это протокол, управляющий редактированием и взаимодействием с текстом. Основные методы: textViewDidBeginEditing(textView) — вызывается при старте редактирования; textViewDidEndEditing — при завершении; textViewDidChange — при каждом изменении текста; textViewDidChangeSelection — при изменении выделения; textViewShouldInteractWithURL — при нажатии на ссылку (возвращает Bool, разрешён ли переход); textViewShouldInteractWithTextAttachment — при нажатии на встроенное изображение. Для обработки ссылок внутри UITextView переопределите shouldInteractWithURL — в нём можно: открыть URL в SFSafariViewController, показать UIAlertController для подтверждения, обработать кастомные URL schemes. Важно: если textView.isEditable = true, ссылки становятся недоступными для нажатия до двойного тапа — для интерактивных ссылок при редактировании используйте gesture recognizers.

Обработка ссылок через SFSafariViewController

SFSafariViewController — стандартный способ открытия ссылок в iOS приложениях. В методе shouldInteractWithURL создайте SFSafariViewController с URL и представьте его модально или через navigationController. Для универсальных ссылок используйте UIApplication.shared.open(url, options) — но это выходит за пределы приложения. Для запрета открытия ссылок верните false в shouldInteractWithURL и обработайте URL самостоятельно.

Система Text Container: отступы и exclusionPaths

NSTextContainer — часть архитектуры TextKit, определяющая геометрическую область, в которой отображается текст UITextView. Каждый UITextView имеет стандартный textContainer, настраиваемый через: textView.textContainerInset — отступы текста от границ textView (UIEdgeInsets); textView.textContainer.lineFragmentPadding — горизонтальный отступ внутри каждой строки; textView.textContainer.maximumNumberOfLines — ограничение количества строк (0 = без лимита); textView.textContainer.exclusionPaths — массив UIBezierPath для областей, которые текст должен обтекать (изображения, кастомные shapes). ExclusionPaths позволяют создавать сложную вёрстку: текст обтекает круглое изображение профиля, иконку или любой произвольный контур. Для динамического размера UITextView наблюдайте contentSize через KVO или делегат и обновляйте constraints.

swift
// Dynamic UITextView height via contentSize
func textViewDidChange(textView: UITextView) {
    let fixedWidth = textView.frame.size.width
    let newSize = textView.sizeThatFits(
        CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude)
    )
    heightConstraint.constant = newSize.height
    UIView.animate(withDuration: 0.1) {
        self.view.layoutIfNeeded()
    }
}

// ExclusionPath for image wrapping
let imageFrame = CGRect(x: 16, y: 100, width: 80, height: 80)
let exclusionPath = UIBezierPath(rect: imageFrame)
textView.textContainer.exclusionPaths = [exclusionPath]

Data Detector Types: автоопределение данных

dataDetectorTypes — свойство UITextView, которое автоматически распознаёт и делает интерактивными определённые типы данных в тексте: .link (URL, email), .phoneNumber (телефонные номера), .address (адреса), .calendarEvent (даты и события), .flightNumber (номера рейсов), .lookupSuggestion (поисковые подсказки), .trackingNumber (трекинг-номера), .money (суммы), .shipmentTrackingNumber, .all (все типы). Data Detector работает с NSDataDetector и URL, автоматически подсвечивая обнаруженные данные. Для кастомизации обработки установите dataDetectorTypes и переопределите shouldInteractWithURL в делегате. Важно: dataDetectorTypes работает только для URL и phoneNumber без дополнительной настройки — остальные типы могут требовать iOS 16+. Data Detector не конфликтует с link attribute в NSAttributedString — оба механизма работают параллельно. Для read-only UITextView с контентом (новости, статьи) установите dataDetectorTypes = [.link, .phoneNumber].

  • .link — URL, email адреса; отображаются как синие ссылки
  • .phoneNumber — телефонные номера; нажатие показывает Call action
  • .address — почтовые адреса; нажатие открывает Maps
  • .calendarEvent — даты и время; нажатие создаёт событие календаря
  • .flightNumber — номера рейсов (iOS 16+); быстрая проверка рейса

Примеры кода с UITextView

Рассмотрим два практических примера использования UITextView в iOS приложениях. Первый — read-only text view с атрибутированным текстом и data detector для отображения контента. Второй — редактируемый text view с ленивым placeholder и динамической высотой для формы комментария. Оба примера используют best practices UIKit: делегатный протокол, Auto Layout и TextKit.

Read-only UITextView с контентом и ссылками

Read-only режим включается установкой isEditable = false и isSelectable = true. Это позволяет пользователю выделять текст и нажимать на ссылки, но не редактировать. Установите dataDetectorTypes для автоопределения ссылок, backgroundColor = .clear для прозрачного фона. Для отображения длинного контента используйте attributedText с NSMutableParagraphStyle lineSpacing для читаемости. Добавьте link attributes для ключевых ссылок внутри текста.

swift
import UIKit

class ArticleViewController: UIViewController {
    let contentView = UITextView()

    override func viewDidLoad() {
        super.viewDidLoad()
        contentView.isEditable = false
        contentView.isSelectable = true
        contentView.dataDetectorTypes = [.link, .phoneNumber]
        contentView.backgroundColor = .clear
        contentView.textContainerInset = UIEdgeInsets(
            top: 8, left: 16,
            bottom: 8, right: 16
        )
        contentView.delegate = self
        loadArticleContent()
    }

    func loadArticleContent() {
        guard let url = URL(string: "https://example.com/article")
        else { return }
        // Load content from URL and set attributedText
    }
}

Редактируемый UITextView с placeholder

Placeholder для UITextView не встроен — реализуйте его через UILabel поверх textView или через attributedText с проверкой isEmpty. Простой подход: UILabel с серым текстом, который скрывается при начале редактирования. В textViewDidChange проверяйте наличие текста и скрывайте/показывайте placeholder. Для более элегантного решения используйте свойство typingAttributes для установки цвета вводимого текста. Динамическая высота textView достигается через наблюдение contentSize и обновление constraints — это стандартный паттерн для чатов и форм комментариев.

Часто задаваемые вопросы

Как добавить placeholder в UITextView?

UITextView не имеет встроенного placeholder. Стандартное решение: добавьте UILabel с серым текстом поверх textView. В textViewDidBeginEditing скрывайте label, в textViewDidEndEditing показывайте, если текст пуст. Альтернативно: используйте attributedText с серым цветом как placeholder и сбрасывайте при начале редактирования. Для готового решения используйте библиотеку KMPlaceholderTextView или ReactorKit.

Как убрать отступы в UITextView?

Установите textContainerInset = .zero и lineFragmentPadding = 0: textView.textContainerInset = UIEdgeInsets.zero; textView.textContainer.lineFragmentPadding = 0. Дополнительно: textView.contentInset = .zero. Это полностью удалит отступы от краёв textView до текста. Учтите, что lineFragmentPadding по умолчанию равен 5.

Почему UITextView не открывает ссылки?

Проверьте: isSelectable = true (необходимо для взаимодействия), dataDetectorTypes включает .link, делегат не возвращает false в shouldInteractWithURL. Если textView.isEditable = true, ссылки недоступны для одноразового нажатия — требуется двойной тап. Для интерактивных ссылок в редактируемом textView добавьте UITapGestureRecognizer поверх textView и обрабатывайте URL вручную.

Как сделать UITextView фиксированной высоты с прокруткой?

Установите isScrollEnabled = true и добавьте height constraint с фиксированным значением. Текст, превышающий высоту, будет прокручиваться. Для оптимального UX используйте maxHeight: наблюдайте contentSize и устанавливайте height constraint не выше maxHeight. При превышении maxHeight включайте scrollEnabled. Это стандартный паттерн для полей ввода сообщений и комментариев.

Как вставить изображение в UITextView?

Используйте NSTextAttachment: создайте объект, установите image и bounds, затем создайте NSAttributedString из attachment и вставьте в textView.attributedText. Пример: let attachment = NSTextAttachment(); attachment.image = image; attachment.bounds = CGRect(x, y, width, height); let attributedString = NSAttributedString(attachment: attachment). Изображение отобразится inline в тексте и будет прокручиваться вместе с ним.

Итоги

  • UITextView — многострочный текстовый компонент UIKit, наследник UIScrollView с поддержкой TextKit
  • NSAttributedString — ключевая возможность для форматирования шрифтов, цветов, ссылок и параграфов
  • UITextViewDelegate — управление редактированием и обработка нажатий на ссылки и вложения
  • Data Detector Types — автоопределение URL, телефонов, адресов и дат через NSDataDetector
  • Text Container — система с exclusionPaths, lineFragmentPadding и textContainerInset для вёрстки
  • Placeholder — не встроен, реализуется через UILabel или attributedText с серым цветом
  • Dynamic height — наблюдение contentSize и обновление constraints для авто-высоты
  • UITextView отличается от UITextField поддержкой многострочности, атрибутов, прокрутки и data detectors

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также