‘
利用 NSTextAttachment 製作包含圖片的字串-喜好探測機
這篇分享主要是用來跟大家說如何在Label中放入一些圖片,可以利用這個方式來做一些應用,例如用圖像表達一些字義,那麼我們先來看一下畫面。
常常可以看到一些軟體用兩個按鍵來表達喜歡與不喜歡,透過問題或圖片來讓使用者做選擇,並依據使用者一步一步的選擇最後給出答案,舉凡appstore上的交友軟體?!或一些心理測驗等一些需要闖關的方式,都可以利用這種方式來實現。
這個應用不用寫太多程式,就可以完成了!
參考教學
找素材
首先我們要找一些表情圖案,因為沒有背景,使用上比較方便,不需要考慮太多,如我們手機輸入時可以採用的表情符號emoji。
這次我所採用的素材網站只需要註冊,就可以免費下載到一些常用的emoji,大家可以參考看看。
下載解壓縮後,可以看到有不同大小和格式的emoji,所以就依照主題來挑選個幾張來做這個喜好探測機。
將圖片放入Xcode的Assets.xcassets
main.storyboard建置畫面
這個畫面應用了UIButton、LabelX2,一個Label用來顯示標題,一個用來顯示待會問題顯示的區塊,兩顆按鈕則是套上了一個like和unlink的圖案。
建立ViewController Class
這個畫面因為是問使用者問題,所以我沒有採用預設提供的ViewController Class,所以這步驟看個人。
建立IBOutlet
因為我們即將在程式中使用到Label來顯示問題,所以我們要將quesdtionLabel與viewController建立連結關係。
要問的問題很多,所以需要靠陣列和物件來儲存問題
新增一個swift file,並命名為question,也就是新增一個問題,需要遵循我所定義的資料架構,宣告了imageAttributeStr來存放中文字義,用imageSrc來定義圖片來源名稱,最後imageObj是用來宣告未來要放入Label所需要的物件格式-NSTextAttachment。
關於NSTextAttachment的解釋,要從NSMutableAttributedString開始說起:
目前只有 NSAttributedString 可以在文字區塊中加上圖片,普遍我們所認識的 String 無法,有這個物件,我們變成可以在文字的任何位置上放入圖片,有點類似Office Word中的文繞圖感覺。
init的func則是在建立這個物件時,會執行的func,有點類似我們所認識的建構子,而兩個參數則代表是物件初始化所需要的參數。
getNS則是回傳我們這次所需要的物件NSTextAttachment,利用方法image可以指定一個UIImage。
建立圖片物件
let questionObj = question(imageAttributeStr:”釣魚”,imageSrc:”fishing-pole”)
由於很多張圖片,為了能夠一個一個呈現給使用者,我們宣告了陣列來存放這些圖片。
將圖片顯示於畫面上
由於圖片顯示與切換是畫面載入時和點選like和unlike都要做的事情,所以為了方便維護起見,我們宣告了func來做圖片的顯示與處理。
signAsk:問號的圖示
//將問號的圖示指定其大小與位置
signAsk.getNS().bounds = CGRect(x: 0, y: -5, width: 30, height: 30)
開始使用NSMutableAttributedString
//宣告
let content = NSMutableAttributedString(string: “你喜歡”)
//將NSMutableAttributedString指定為questionLabel顯示內容
questionLabel.attributedText = content
//指定一個itemIndex來記錄目前顯示到第幾個,起始值為0
var itemIndex = 0
//並且判斷其陣列的圖片數量大於itemIndex
if questionAry.count > itemIndex{…}
將圖片加入content (NSMutableAttributedString)
//取得圖片NSTextAttachment物件
let questionOBj = questionAry[itemIndex]
//將上述物件記錄下來,是為了在按下按鈕時可以得知他點的物件是哪一個
currentImage = questionOBj
//使用append的方是加入NSAttributedString
content.append(NSAttributedString(attachment:questionOBj.getNS()))
//結束問題
content.append(NSAttributedString(string: “嗎”))
//加入問號
content.append(NSAttributedString(attachment:signAsk.getNS()))
//指定其content內容為label顯示內容
questionLabel.attributedText = content
若已經玩完了,代表itemIndex已經大於圖片數量時,顯示結果
//改變label文字大小
questionLabel.font = questionLabel.font.withSize(20)
//改變label顯示行數
questionLabel.numberOfLines = 20
//重新組出label內容,計算likeItem有多少物件,並append起來
let content = NSMutableAttributedString(string: “統計結果\n\n”)
for likeObj in likeItem{
//改變圖片物件內的表情符號大小與顯示位置
likeObj.getNS().bounds = CGRect(x: 0, y: -5, width: 20, height: 20)
content.append(NSAttributedString(string:”你喜歡”))
content.append(NSAttributedString(string:likeObj.imageAttributeStr))
content.append(NSAttributedString(attachment:likeObj.getNS()))
content.append(NSAttributedString(string: “\n”))
questionLabel.attributedText = content
}
//重新組出label內容,計算unlikeItem有多少物件,並append起來
for unlikeObj in unlikeItem{
//改變圖片物件內的表情符號大小與顯示位置
unlikeObj.getNS().bounds = CGRect(x: 0, y: -5, width: 20, height: 20)
content.append(NSAttributedString(string:”你不喜歡”))
content.append(NSAttributedString(string:unlikeObj.imageAttributeStr))
content.append(NSAttributedString(attachment:unlikeObj.getNS()))
content.append(NSAttributedString(string: “\n”))
questionLabel.attributedText = content
}
按鈕部分的操作
按鈕按下時,我們必須記錄使用者喜歡的這個物件是什麼,所以顯示時就已經將currentImage存放了目前畫面顯示的這個物件,所以也是宣告一個likeItem的陣列來存放使用者喜歡的物件,相反,不喜歡的做法也是,因為這個一個二選一,也就是只有喜歡與不喜歡兩種選擇!
於是我們需要將按鈕建立IBAction!
程式中我們就是判斷是否還有下一個問題,若有則是將itemIndex + 1且繼續呼叫showQuestion,同時記錄使用者喜歡這個運動。
成果分享
Github