#70 利用 NSTextAttachment 製作包含圖片的字串

想要顯示文字和圖片,一般我們會用 label & image view 實現。彼得潘為了促進台灣經濟發展,想用 label & image view 顯示以上畫面,每天喝十杯珍奶,每天吃一百顆小籠包,以可愛的圖片表示珍奶和小籠包。

然而它卻沒有想像中簡單,因為我們得小心控制 image view 的大小和位置,才能讓圖文排列整齊。

既然 image view 如此麻煩,不如拋棄它吧。其實只要 label 就能搞定!利用 NSAttributedString 和 NSTextAttachment,label 就能排出包含美麗圖片的文字。

題目

在 label 上顯示一段包含台灣 emoji 圖片的有趣文字。(或是使用其它你喜歡的圖片和文字當主題。)

可愛的台灣 emoji 圖片下載連結。

範例說明

1 下載可愛的台灣 emoji 圖片。

2 將圖片加到 playground。

圖片加入的方法可參考以下連結。

3 產生 NSMutableAttributedString 物件。

let content = NSMutableAttributedString(string: "為了促進台灣經濟發展,我要每天喝十杯")

只有 NSAttributedString 可以包含圖片,一般的 String 無法,而且我們之後還會增加字串的內容,因此我們生成可以改變的 NSMutableAttributedString。(Mutable 是可以改變的意思)

4 產生包含珍奶圖片的 NSTextAttachment 物件。

NSTextAttachment 可以包含圖片,之後我們將利用它生成包含圖片的 NSAttributedString。

let bubbleTeaAttachment = NSTextAttachment()
bubbleTeaAttachment.image = UIImage(named: "Bubble_Tea_128x128")

5 生成 NSAttributedString 時傳入 bubbleTeaAttachment,產生包含圖片的文字,然後將它加到 content 上。

content.append(NSAttributedString(attachment: bubbleTeaAttachment))

6 將 label 的 attributedText 設為 content,顯示包含圖片的文字。

let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
label.numberOfLines = 0
label.attributedText = content

結果

Cool,珍奶圖片出現了 ! 不過它也太大杯了,我們希望它能小一點,呈現圖文排列成一段話的感覺。

設定 NSTextAttachment 的大小位置

import UIKit

let content = NSMutableAttributedString(string: "為了促進台灣經濟發展,我要每天喝十杯")
let bubbleTeaAttachment = NSTextAttachment()
bubbleTeaAttachment.image = UIImage(named: "Bubble_Tea_128x128")
bubbleTeaAttachment.bounds = CGRect(x: 0, y: 0, width: 30, height: 30)
content.append(NSAttributedString(attachment: bubbleTeaAttachment))
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
label.numberOfLines = 0
label.attributedText = content

說明

bubbleTeaAttachment.bounds = CGRect(x: 0, y: 0, width: 30, height: 30)

剛剛生成 NSTextAttachment 物件時,我們可以透過 CGRect 型別的 property bounds 設定圖片的位置大小。如下圖所示,設為 CGRect(x: 0, y: 0, width: 30, height: 30) 後,文字十杯和珍奶圖片完美地串在一起。

不過珍奶圖片感覺有點偏上,沒關係,我們可以將 bounds 的 y 設為 -5,讓圖片往下移動一點。

bubbleTeaAttachment.bounds = CGRect(x: 0, y: -5, width: 30, height: 30)

bounds 的 y > 0 將讓圖片往上移動,y < 0 則往下移動,比方 y 等於 25 將產生以下畫面。

bubbleTeaAttachment.bounds = CGRect(x: 0, y: 25, width: 30, height: 30)

學會 NSTextAttachment 的使用技巧後,現在讓我們發揮創意,產生以下促進台灣經濟發展的感人宣言。

import UIKit

let content = NSMutableAttributedString(string: "為了促進台灣經濟發展,我要每天喝十杯")
let bubbleTeaAttachment = NSTextAttachment()
bubbleTeaAttachment.image = UIImage(named: "Bubble_Tea_128x128")
bubbleTeaAttachment.bounds = CGRect(x: 0, y: -5, width: 30, height: 30)
content.append(NSAttributedString(attachment: bubbleTeaAttachment))
content.append(NSAttributedString(string: ",每天吃一百顆"))
let xiaoLongBaoAttachment = NSTextAttachment()
xiaoLongBaoAttachment.image = UIImage(named: "Xiaolongbao_128x128")
xiaoLongBaoAttachment.bounds = CGRect(x: 0, y: -5, width: 30, height: 30)
content.append(NSAttributedString(attachment: xiaoLongBaoAttachment))
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
label.numberOfLines = 0
label.attributedText = content

其它範例: 圖文並茂歌詞

作品集

--

--

彼得潘的 iOS App Neverland
彼得潘的 100 道 Swift iOS App 謎題

彼得潘的iOS App程式設計入門,文組生的iOS App程式設計入門講師,彼得潘的 Swift 程式設計入門,App程式設計入門作者,http://apppeterpan.strikingly.com