這是本單元最後一節課。
TapGesture 是點按(或輕點、點選)的手勢操作,與滑鼠的點擊(Click)操作類似,也可以連續兩次點按,我們練習將表情符號(Emoji)改用 List 列表,然後讓每個表情符號可以點按一次則改變顏色,或點按兩次則放大並拷貝字元。
拷貝字元到剪貼簿的方法是借用舊有的 UIKit 一個物件UIPasteboard:
UIPasteboard.general.string = 符號.char就會將符號字元拷貝到剪貼簿中。
範例程式如下,前半段用傑森解碼器讀取Emoji列表的程式碼跟範例程式2-8b是一樣的:
// 2-10c Emoji (TapGesture)
// Revised from 2-8b by Heman, 2021/08/26
import PlaygroundSupport
import SwiftUI
struct 表情符號: Codable {
var codes: String
var char: String
var name: String
var category: String
var group: String
var subgroup: String
}
func 傑森解碼器(_ 檔名: String) -> [表情符號]? {
if let 檔案 = Bundle.main.url(forResource: 檔名, withExtension: "") {
do {
let 資料 = try Data(contentsOf: 檔案)
let 結果 = try JSONDecoder().decode([表情符號].self, from: 資料)
return 結果
} catch {
print("error:\(error)")
}
}
return nil
}
let 表情符號全集 = 傑森解碼器("emoji.json") ?? []
struct 顯示表情: View {
@State var 點選 = false
@State var 放大 = false
var 符號: 表情符號
init(_ p: 表情符號) { 符號 = p }
var body: some View {
HStack {
Text(符號.char)
.font(.system(size: 放大 ? 96 : 36))
VStack(alignment: .leading) {
Text(符號.category)
Text(符號.name)
}
.lineLimit(1)
.font(放大 ? .title : .title2)
.foregroundColor(點選 ? .orange : .primary)
}
.onTapGesture(count: 2) {
UIPasteboard.general.string = 符號.char
放大.toggle()
}
.onTapGesture {
點選.toggle()
}
}
}
struct 顯示表情符號: View {
var body: some View {
List(表情符號全集, id: \.codes) {字符 in
顯示表情(字符)
}
}
}
PlaygroundPage.current.setLiveView(顯示表情符號())
執行結果畫面如下,點按一次則變成橙色,點按兩次則放大,並且將表情符號字元拷貝到剪貼簿:

實現這個操作的程式碼如下:
struct 顯示表情: View {
@State var 點選 = false
@State var 放大 = false
private var 符號: 表情符號
init(_ p: 表情符號) { 符號 = p }
var body: some View {
HStack {
Text(符號.char)
.font(.system(size: 放大 ? 96 : 36))
VStack(alignment: .leading) {
Text(符號.category)
Text(符號.name)
}
.lineLimit(1)
.font(放大 ? .title : .title2)
.foregroundColor(點選 ? .orange : .primary)
}
.onTapGesture(count: 2) {
UIPasteboard.general.string = 符號.char
放大.toggle()
}
.onTapGesture {
點選.toggle()
}
}
}
設定了兩個「狀態變數」,「點選」對應點按一次的手勢,「放大」對應點按兩次,如何得到點按兩次的訊號呢?就是 onTapGesture(count: 2) 加上參數即可,沒有加參數時,預設的 count 為 1,就是點按一次。
每個表情符號用 HStack + VStack 來呈現符號與名稱、類別,在最外的 HStack 加兩個手勢操作的修飾語:
.onTapGesture(count: 2) {
UIPasteboard.general.string = 符號.char
放大.toggle()
}
.onTapGesture {
點選.toggle()
}
做法跟前2節介紹的一樣,都是藉由改變「狀態變數」來帶動畫面的變化。
執行的動態影片如下:


































































































