NSTextAttachment: 개요와 iOS에서 텍스트에 이미지 추가하는 방법

저자: IT Sectr 게시일: 2026-07-25 읽는 시간: 9 분

NSTextAttachment는 UIKit 프레임워크의 클래스로, NSAttributedString을 통해 서식이 지정된 텍스트에 이미지 및 기타 미디어 객체를 삽입할 수 있습니다. TextKit 및 Core Text 수준에서 작동하며, 개발자에게 텍스트 흐름 내에서 첨부 파일의 크기, 위치 및 동작을 제어할 수 있는 기능을 제공합니다. Apple Documentation(2025)에 따르면 NSTextAttachment는 이미지, PDF 및 사용자 정의 뷰 컨테이너를 지원하며 UITextView 및 UILabel과 통합됩니다. iOS 애플리케이션에서 리치 텍스트를 만들기 위해 이 API를 이해하는 것이 필요합니다. 채팅 및 편집기부터 캡션에 아이콘이 있는 뉴스 피드까지 다양하게 사용됩니다.

주요 포인트

  • NSTextAttachment는 서식이 지정된 iOS 텍스트에 미디어를 삽입하기 위한 UIKit 클래스입니다.
  • 이미지는 NSAttributedString의 NSAttachmentAttributeName 키를 사용하여 추가됩니다.
  • bounds 속성은 첨부 파일의 크기와 수직 오프셋을 제어합니다.
  • NSTextAttachment는 데이터 컨테이너를 통해 이미지, PDF 및 사용자 정의 파일을 지원합니다.
  • API는 유연한 텍스트 레이아웃을 위해 UITextView, UILabel 및 TextKit과 통합됩니다.

NSTextAttachment란?

NSTextAttachment는 UIKit 프레임워크의 클래스로, 미디어 객체를 NSAttributedString의 텍스트 콘텐츠에 직접 삽입할 수 있습니다. 텍스트 옆에 배치되는 별도의 UIImageView와 달리, NSTextAttachment는 이미지를 텍스트 흐름의 일부로 만듭니다. 이미지는 줄과 함께 줄 바꿈되고, 정렬에 참여하며, 일반 문자처럼 공간을 차지합니다.

이 클래스는 iOS 및 macOS에서 텍스트 렌더링을 관리하는 TextKit 아키텍처의 일부입니다. TextKit는 텍스트를 글리프로 분해하고, 커닝, 합자 및 행간을 고려합니다. NSTextAttachment는 이 파이프라인에 특수 문자로 포함되어 문자로가 아닌 그래픽 객체로 렌더링됩니다.

각 NSTextAttachment 인스턴스에는 contents(파일 데이터), fileType(UTI 콘텐츠 유형) 및 bounds(크기와 위치를 정의하는 포인트 단위의 사각형)가 포함됩니다. Apple Human Interface Guidelines에 따르면 bounds는 기본적으로 이미지 크기이지만 폰트에 정확히 맞추기 위해 변경할 수 있습니다.

이미지가 텍스트의 일부로 작동해야 하는 경우(채팅, 뉴스 피드, 텍스트 편집기, 입력 필드에 아이콘이 있는 양식 등) 별도의 UIImageView 대신 NSTextAttachment를 사용하세요.

NSTextAttachment를 통해 텍스트에 이미지 추가하는 방법

NSTextAttachment의 기본 작업 흐름은 세 단계로 구성됩니다: 인스턴스 생성, 이미지 설정, NSAttributedString에 첨부. Swift를 사용하여 프로세스를 살펴보겠습니다.

swift
let attachment = NSTextAttachment()
attachment.image = UIImage(named: "icon-star")

let attachmentString = NSAttributedString(attachment: attachment)

let text = NSMutableAttributedString(string: "Rating: ")
text.append(attachmentString)

let label = UILabel()
label.attributedText = text

NSAttributedString(attachment:)을 호출한 후 NSTextAttachment 객체는 NSAttachmentAttributeName 속성으로 변환되어 특수 객체 대체 문자(코드 0xFFFC)에 첨부됩니다. 이 문자는 문자로 표시되지 않고 대신 image 속성의 이미지가 그 자리에 그려집니다.

이미지를 텍스트 줄 중간에 배치해야 하는 경우(예: 단어 뒤의 아이콘), NSMutableAttributedString의 원하는 위치에 attachmentString을 삽입하기만 하면 됩니다. TextKit는 자동으로 줄 높이를 고려하여 이미지를 기준선에 정렬합니다.

중요: image 속성은 iOS에서만 사용 가능합니다(iOS 7부터). macOS에서는 NSImage와 함께 contents 속성을 사용하세요. 이전 버전과의 호환성을 위해 데이터 컨테이너에 의존하기보다 항상 직접 image를 설정하는 것이 좋습니다.

bounds 및 첨부 파일 위치 구성

기본적으로 NSTextAttachment는 이미지를 포인트 단위의 원래 크기로 표시합니다. 실제로는 거의 항상 크기와 수직 위치를 조정해야 합니다. 이는 bounds 속성을 사용하여 수행됩니다.

CGRect bounds 구조체에는 origin(X 및 Y 오프셋)과 size(너비 및 높이)가 포함됩니다. Y 오프셋은 특히 중요합니다: 음수 값은 이미지를 기준선 아래로 내리고, 양수 값은 올립니다. 일반적인 시나리오는 아이콘을 텍스트 줄의 중앙에 정렬하는 것입니다.

swift
let attachment = NSTextAttachment()
attachment.image = UIImage(named: "icon-star")

let font = UIFont.systemFont(ofSize: 16)
let fontCapHeight = font.capHeight
let imageSize = CGSize(width: 18, height: 18)

attachment.bounds = CGRect(
    x: 0,
    y: (fontCapHeight - imageSize.height) / 2,
    width: imageSize.width,
    height: imageSize.height
)

정렬 계산은 폰트의 capHeight를 사용합니다(전체 줄 높이가 아닌 대문자의 높이). 이렇게 하면 아이콘이 기준선과 어센더 사이에 떠 있지 않고 텍스트의 위쪽 가장자리와 시각적으로 일치합니다. 예제의 이미지 크기는 18×18pt로 UI 텍스트의 아이콘에 일반적입니다.

이미지가 텍스트 줄보다 큰 경우(예: 채팅의 사진 미리보기), TextKit는 현재 줄의 줄 간격을 자동으로 늘립니다. 이 경우 bounds는 자연스러운 크기로 설정하고 Y 오프셋은 0으로 설정해야 합니다.

PDF 및 사용자 정의 첨부 파일

NSTextAttachment는 PNG 및 JPEG뿐만 아니라 PDF 문서와 contents 속성을 통한 임의의 파일도 지원합니다. 이는 iOS 애플리케이션에서 리치 텍스트를 위한 범용 도구로 만듭니다.

attachment.image에 PDF 이미지를 설정하면 시스템이 자동으로 문서의 첫 페이지를 렌더링합니다. 그러나 정확한 렌더링을 위해 데이터와 UTI 유형이 있는 초기화자를 통해 직접 데이터를 사용하세요:

swift
guard let pdfData = Bundle.main.url(forResource: "document",
                                  withExtension: "pdf") else { return }

let fileData = Data(contentsOf: pdfData)
let attachment = NSTextAttachment(data: fileData,
                                       ofType: "com.adobe.pdf")

attachment.bounds = CGRect(x: 0, y: -4,
                           width: 24, height: 24)

let pdfString = NSAttributedString(attachment: attachment)

ofType 매개변수는 UTI 문자열(Uniform Type Identifier)을 허용합니다. 표준 유형에는 public.image(모든 이미지), public.jpeg, public.png, com.adobe.pdf가 포함됩니다. 올바른 UTI를 지정하면 시스템이 적절한 렌더링 방법을 선택합니다. PDF의 경우 CGPDFDocument, 이미지의 경우 CGImageSource입니다.

사용자 정의 파일 유형(예: SVG 형식의 벡터 그래픽)의 경우 image(forBounds:textContainer:characterIndex:) 메서드를 재정의하는 NSTextAttachment의 하위 클래스가 필요합니다. 표준 렌더링이 적합하지 않은 경우 nil을 반환하고 draw 메서드에서 Core Graphics를 통해 그리기를 구현합니다.

UITextView의 NSTextAttachment 및 위임

NSTextAttachment는 UILabelUITextView 모두에서 올바르게 작동합니다. 그러나 UITextView는 더 많은 기능을 제공합니다: 첨부 파일과의 상호 작용(아이콘 탭), 이미지와 함께 텍스트 편집, NSAttachmentBehavior 지원.

UITextView에서 NSTextAttachment 탭을 처리하려면 UITextViewDelegate 프로토콜과 textView(_:shouldInteractWith:in:interaction:) 메서드를 사용하세요. 이 메서드는 사용자가 첨부 파일을 탭할 때 호출되며 화면 탐색, 팝업 열기 또는 애니메이션 재생을 가능하게 합니다.

swift
func textView(_ textView: UITextView,
                shouldInteractWith attachment: NSTextAttachment,
                in characterRange: NSRange,
                interaction: UITextItemInteraction) -> Bool {
    if interaction == .preview {
        return false
    }
    // 세부 화면 열기
    showImageDetail(attachment.image)
    return false
}

이 메서드는 interaction 매개변수를 통해 상호 작용 유형을 구분합니다: .preview(3D Touch / Haptic Touch), .default(일반 탭), .presentActions(컨텍스트 메뉴). 각 유형에 대해 자체 동작을 정의하거나 false를 반환하여 비활성화할 수 있습니다.

NSTextAttachment로 UITextView를 편집할 때 중요하게 기억해야 할 점: 대체 문자(0xFFFC)를 삭제하면 첨부 파일도 삭제됩니다. 사용자는 이미지를 단일 요소로 보며 픽셀 단위가 아니라 전체로 선택됩니다. iOS 15+에서 첨부 파일의 드래그 앤 드롭 지원을 위해 NSTextAttachmentViewProvider를 사용하세요.

NSTextAttachment 사용 시 일반적인 오류

첫 번째 일반적인 오류는 bounds 무시입니다. 개발자는 종종 원본 이미지 크기에 의존하여 텍스트에 거대한 아이콘이 생기거나 반대로 거의 보이지 않는 이미지가 생깁니다. 항상 폰트와 컨텍스트를 고려하여 bounds를 명시적으로 설정하세요.

두 번째 오류는 잘못된 Y 오프셋입니다. bounds.origin.y의 양수 값은 이미지를 아래로 내립니다(UIKit의 좌표계에서 Y축은 아래쪽을 가리킵니다. 직관에 어긋나지만 Core Graphics의 작동 방식입니다). 줄 내에서 중앙 정렬하려면 섹션 3에 표시된 대로 폰트의 capHeight를 사용한 공식을 사용하세요.

세 번째 문제는 traitCollection 변경 시 이미지 손실입니다. 사용자가 다크 모드 또는 Dynamic Type을 전환하면 폰트 크기가 변경될 수 있지만 bounds는 그대로 유지됩니다. 해결책은 layoutSubviews 메서드에서 또는 폰트의 KVO를 통해 bounds를 동적으로 계산하는 것입니다.

네 번째 빈번한 오류는 numberOfLines > 1인 UILabel에서 NSTextAttachment 사용입니다. 제한된 너비의 여러 줄 모드에서 TextKit는 이미지와 함께 줄을 올바르게 줄 바꿈합니다. 문제는 첨부 파일 높이가 줄 높이를 초과할 때 발생하여 인접한 줄이 서로 겹칩니다. 해결책은 NSMutableParagraphStyle을 통해 lineSpacing을 늘리는 것입니다.

자주 묻는 질문

텍스트에서 NSTextAttachment와 UIImageView의 차이점은?

NSTextAttachment는 이미지를 텍스트 흐름의 일부로 만듭니다: 텍스트와 함께 줄 바꿈, 정렬 및 크기 조정이 됩니다. UIImageView는 슈퍼뷰 좌표에 바인딩되며 텍스트 레이아웃에 참여하지 않습니다.

UILabel에 NSTextAttachment를 추가할 수 있나요?

네, text 대신 attributedText 속성을 설정하면 가능합니다. UILabel은 NSTextAttachment를 올바르게 표시하지만 상호 작용을 지원하지 않습니다. 첨부 파일 탭에는 UITextView를 사용하세요.

첨부 파일 생성 후 이미지 크기를 변경하려면?

기존 NSTextAttachment 인스턴스의 bounds 속성을 변경하세요. 새 NSAttributedString을 만들 필요 없이 텍스트가 자동으로 새 크기로 다시 렌더링됩니다.

NSTextAttachment는 애니메이션 이미지를 지원하나요?

NSTextAttachment는 정적 이미지를 지원합니다. GIF 및 애니메이션 형식의 경우 iOS 15+의 NSTextAttachmentViewProvider 또는 CADisplayLink를 통한 사용자 정의 구현이 필요합니다.

프로그래밍 방식으로 텍스트에 NSTextAttachment를 추가하려면?

NSTextAttachment 인스턴스를 생성하고, 이미지 또는 데이터를 설정하고, bounds를 설정하고, NSAttributedString(attachment:)으로 감싼 다음 insert(_:at:) 메서드를 사용하여 NSMutableAttributedString에 삽입합니다.

요약

  • NSTextAttachment는 서식이 지정된 텍스트에 이미지, PDF 및 기타 미디어를 삽입하기 위한 UIKit 클래스입니다.
  • 이미지는 NSAttributedString(attachment:)을 통해 추가되며 텍스트 흐름의 일부가 됩니다.
  • bounds 속성은 크기와 위치를 제어합니다: 항상 폰트를 고려하여 명시적으로 설정하세요.
  • 줄 내에서 아이콘을 중앙에 배치하려면 현재 폰트의 capHeight를 사용한 공식을 사용하세요.
  • PDF 첨부 파일은 data와 올바른 UTI 유형이 있는 초기화자를 통해 지원됩니다.
  • 첨부 파일 탭 처리를 위해 UITextViewDelegate와 shouldInteractWith 메서드를 사용하세요.
  • Dynamic Type 변경 시 줄 겹침을 피하기 위해 bounds를 동적으로 다시 계산하세요.

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기