taste-skill-swiftui 是做什麼的?
AI 模型所建構的應用程式畫面,看起來就像是它見過的所有應用程式畫面的平均值:一個四個分頁的 TabView、一個大標題、一個含有圓角卡片的 List,每個卡片裡都有個放在有色正方形中的 SF Symbol、一個藍色漸層的「開始使用」按鈕、一個三頁符號引導頁、一個會發光的付費牆。其中的每個元素都沒有錯,但也沒有任何一個元素是經過決策的。
這項技能透過四種方式,用經過深思熟慮的決策取代那些預設值:
- 腳本提供方向,你從中選擇。 要求模型發想一個外觀時,它每次都只會選取類別的預設值。
scripts/draw.mjs會從十二個經過研究的方向中隨機挑選三個;你選擇最能承載主題核心概念的那個,然後它會再提供字體、色版、形狀、動態以及畫面藍圖。 - 概念來自於主題本身。 最出色的應用程式都是建立在從事物本身(其產出、其物件、其儀式、其印刷製品)提取的基礎上,而不是建立在樣式之上。
- 原生優先,自訂必有目的。 每個元素都遵循一個階梯原則(如下所述)。當核心概念需要時,允許並鼓勵使用自訂元件,但它們必須具備所有原生的行為。
- 看著你做出的成果。
scripts/capture.sh會在裝置矩陣上為應用程式拍照,包含淺色與深色模式、預設與輔助使用字型大小;評審的評分標準會評估這些圖片;修正問題,然後再次檢視。
移除裝飾元素只完成了工作的一半。一個失去了有色正方形、卡片和漸層,卻沒有獲得任何其他東西的畫面是單薄的。另一半是實質內容:設定更大的字體、大片的色彩區域、這個主題世界中的真實照片或手繪物件、每個畫面都承載其完整的內容,以及一個只有這個應用程式才有的、使用者能做的事。
在下面的指令中,<skill> 代表此技能所在的資料夾。請在專案根目錄執行這些指令;工作檔案會放在 .taste-skill/ 目錄下。這些腳本需要 Node 18 或更高版本。capture.sh 需要 Xcode 以及已啟動的模擬器。當 ~/.claude/bin/devlock 存在時,請將每個 xcodebuild 和 simctl 的執行都包裝在 devlock run 中(平行建置曾經耗盡過行程限制)。
原生階梯原則
只爬到核心概念所需的階層,並在報告中記錄每一個第 3 層的元件。
- 系統元件,系統外觀。
NavigationStack、TabView、List、Form、Toggle、Picker、Menu、ContentUnavailableView、具有 detents 的.sheet、ShareLink、Chart、ProgressView。免費獲得:動態字型、旁白、減少動態效果、從右至左書寫模式、液態玻璃效果、鍵盤與指標。對於任何職責屬於平台範疇的控制項,請使用這些元件。 - 系統元件,經過樣式化。 相同的元件,使用你的標記:
ButtonStyle、LabelStyle、ToggleStyle、ListRowBackground、scrollContentBackground(.hidden)、tint、fontDesign、fontWidth、containerShape。大多數的方向都體現在這個層級。 - 自訂元件。 僅在沒有任何系統元件能夠承載該核心概念時使用(例如一個轉盤、一把尺、一張票券、一個舞台、一條時間軸主幹)。一個自訂元件必須具備:透過
@ScaledMetric/Font.custom(relativeTo:)實現的動態字型、44×44pt 的最小點擊區域、包含標籤、數值、特徵與可調整動作的accessibilityElement、減少動態效果的路徑、透過sensoryFeedback實現的觸覺回饋、深色模式、從右至左書寫模式(layoutDirection)、iPad/Mac 上的焦點與指標狀態,以及每個狀態的預覽。一個需要一句話來說明如何使用控制項,代表它需要重新設計,而不是加上說明文字。
永遠不要重建平台已有的東西:不要手繪分頁列、導覽列、開關、提示框、工作表或鍵盤附件,除非該核心概念沒有它們就無法實現。永遠不要手動建立模糊面板;液態玻璃效果應來自系統列、工具列,以及僅在浮動控制項上的系統玻璃 API。
從網頁到行動端:原始規則的對應方式
| Taste-skill (網頁) | 這裡 (原生) |
|---|---|
| 頁面 vs 應用程式畫面 | 應用程式幾乎總是第二種類型。首次啟動畫面、引導頁和付費牆是組合畫面(遵循流程)。列表、設定、表單和詳細資訊畫面是工作畫面(遵循 references/screens.md)。 |
| 主視覺區 | 啟動後的第一個畫面(或主頁分頁)。它需要在三秒內回答「這是什麼,我要做什麼」,使用大尺寸字體或一個大型物件。 |
| 標題在任何寬度下最多兩行 | 在 iPhone SE 寬度和 iPad 上的預設大小為兩行,並在輔助使用字型大小時自動換行(絕不截斷)。 |
| 相等的外邊距,沒有擠在一起的區塊 | 使用系統的佈局邊距(16/20pt);iPad 和橫向模式應使用自己的佈局方式(分割檢視、側邊欄、雙欄),絕不能使用一個置中的手機欄位。 |
| 真實圖片下限(四張) | 每個關鍵畫面至少有一張真實或手繪的視覺元素。SF Symbols 是功能性圖示,絕不能當作圖片使用。 |
| 滾動場景 | scrollTransition、visualEffect、matchedGeometryEffect、navigationTransition(.zoom)、KeyframeAnimator、PhaseAnimator、TimelineView。 |
| 即時互動 | 驚喜時刻:只有這個應用程式才有的互動,具有觸覺回饋,且能單手操作。 |
在真實瀏覽器中的 inspect.mjs | 在模擬器中執行 capture.sh,並對 Swift 原始碼執行 lint.mjs。 |
| 動態效果下限 | 在首次執行和核心流程中,至少要有六個有目的的動態效果時刻;每個效果都必須有減少動態效果的備用方案。 |
| 無玻璃效果 | 沒有手動建立的模糊卡片。系統玻璃效果在系統介面元素上是允許的。 |
| 無等寬字型 | 僅在數字對齊時使用 .monospacedDigit()。不要在程式碼之外使用 design: .monospaced。 |
| 無細線 | 系統繪製的列表分隔線是沒問題的。不要使用裝飾性的 Divider,也不要使用 1pt 外框的圓角卡片。 |
| 結尾 = 精心設計的收尾 | 長畫面的最後一行,或流程的結束狀態,應該是經過設計的,而不是留下空白。 |
執行流程
請按順序執行這些步驟。第 1 到第 5 步驟大約需要幾分鐘,並能決定應用程式是否出色。
1. 閱讀任務簡報與專案
找出真實的內容:主題、目標受眾、使用者在第一分鐘內必須做的一件事、平台與部署目標、現有的設計系統或標記、實際存在的素材(攝影、產品照、插圖、影片片段、圖片工具),以及在重新設計中必須保留的部分(模型、意圖、小工具、購買項目、在地化)。不要圍繞你沒有的素材進行規劃。如果需求很模糊,請做出決定並用一句話說明你的解讀;只在某個缺失的事實會阻礙工作時才發問。
盤點主題:找出八到十二個屬於這個客戶、而非競爭對手的項目。它的名稱及其含義;任務簡報中的數字(分鐘、克數、價格、連續紀錄);它存在的限制(每天一次、離線、一次點擊);它的材質與顏色;它的儀式與使用時機;它世界中的印刷製品(一張票、一個標籤、一張收據、一張時間表、一個護照印章);它的聲音;它的實體手勢(搖晃、吹氣、長按)。第 4 步驟的核心概念就來自這份清單。
2. 撰寫論點
將應用程式列為主張及其證據,首次執行與核心流程中的每個畫面各一行:
畫面:主張 -> 使用者所見或所做,作為證據。
刪除任何沒有主張的畫面。這樣可以避免使用標準的啟動畫面、三個引導頁、權限請求、付費牆、四個分頁的組合。引導頁只有在能讓使用者實際執行一次核心操作時,才有其存在的價值。
3. 抽取方向
node <skill>/scripts/draw.mjs --kind <種類> --brief "<一行關於主題的描述>" \
--screens <按照論點順序的角色> [--tone <基調>] [--have <素材>] \
[--keep palette,type] [--platform ios|ipad|watch|mac|vision] --options 3
這會隨機給出三個方向。將每個方向與你的盤點清單進行比對:哪一個方向能夠承載只有這個客戶才有的東西?選擇那個方向,而不是你最熟悉的那個,並用一句話寫下原因。然後,抽取完整的設計單:
node <skill>/scripts/draw.mjs <相同參數,但不加 --options> --direction <選擇的 id>
--kind:node <skill>/scripts/draw.mjs --list kinds(工具、健康、金融、遊戲、兒童、社交、媒體、生產力、生活風格、創意、商業、其他)。--screens:來自--list roles的角色(引導頁、主頁、詳細資訊、建立、結果、設定、付費牆、空白)。--tone:安靜、大膽、溫暖、技術感、趣味、奢華、編輯。僅在任務簡報要求時使用。--have:現有的素材:photography、product-photo、illustration、video、3d。如果沒有則省略;抽取過程會避免使用依賴這些素材的構圖。--keep palette,type:當品牌或設計系統已經固定了色版和字體時使用。抽取過程只會處理構圖、形狀與動態;你需要將系統的值對應到各個角色上。--seed <n>可以讓抽取結果可重現;設計單會印出它使用的種子值。
採用這份設計單。不要將它與你本來會做的佈局混合在一起。只有在你可以說出理由的情況下,才重新抽取某個項目(--redraw type|palette|shape|motion|screen:<角色>|direction):它違反了品牌限制、需要不存在的素材、或無法容納真實的內容。永遠不要為了讓東西更順手而重新抽取。在報告中記錄每一次重新抽取。使用 --show 重新輸出。
檢查色版是否符合主題。 一個被抽取出來的色版,不僅是一組顏色,也是一組比例(一個底色、一個文字色、一個強調色,以及可選的區域色)。如果它與主題本身的材質衝突,請重新抽取一次,或者保留比例但從主題中提取顏色,並說明你的作法。
4. 找到核心概念
方向是一種構圖方式。核心概念則是讓這個應用程式歸屬於這個主題的東西。在建構之前,先從主題本身填滿這兩個空白:
在這個應用程式中,[某個屬於主題的東西] 變成了 [方向所要求的裝置]。
從以下方向尋找:它的產出(它所產生的東西,以材質呈現)、它的物體(它的形狀,以輪廓呈現)、它的名稱(能承載圖片的文字)、它的地點、它的儀式(應用程式執行的序列)、它的製品(一張票、標籤、收據)、它的反面。
競爭者測試: 將最接近的真實競爭者放入這個句子中。如果它仍然成立,那麼這個概念就屬於這個類別。「簡潔現代」不是一個概念。
驚喜時刻(即時互動)。 賦予應用程式一個每次使用都不同的互動,並從核心概念中產生:對著麥克風吹氣,蠟燭火焰搖曳;設定劑量,讀取真實的半衰期曲線;摺疊手機,卡帶開始播放。它使用真實的內容,可以單手用拇指操作,具有透過 sensoryFeedback 實現的觸覺回饋、減少動態效果的路徑,而且絕不阻礙主要任務。它是一件具體的事,而不是一個遊樂場。它是在第 6 步驟中建構的,而不是在最後才加上動態效果。
5. 撰寫文案
在建立檢視之前,先根據 references/copy.md 撰寫完整的文案稿(純文字),並從第一次提交就將每一個字串放入字串目錄(Localizable.xcstrings)中。每個標題在預設大小下都能容納在兩行內;每個畫面都有一個主要動作,以其功能命名(永遠不要使用「開始使用」、「繼續」(後面沒有接任何內容)、「了解更多」);空白、錯誤和權限的文案現在就寫好,不要以後再補。證據絕不捏造:沒有虛假的評論、使用者數量、獎項或新聞報導。
6. 仍然要建構它
在心中關閉動態效果來進行建構。工作順序如下:
- 標記。 從設計單建立
Palette/Theme,作為具有淺色和深色變體的素材目錄顏色(或一個ShapeStyle標記列舉)、一個Typography列舉、一個Metrics列舉(間距、圓角半徑、一個形狀規則)。所有後續的處理都只參考這些標記。不要在檢視中使用Color(red:)或.font(.system(size: 17))。 - 第一個畫面,完全依照其藍圖的描述, 在 SE 寬度、標準、Pro Max 和 iPad 上進行測試。在建立其他任何東西之前,先讓大的東西變大,小的東西變小。
- 根據藍圖建立每個畫面,並使用這個專案的內容。相鄰的畫面不能共享相同的佈局。將核心概念帶入每個畫面,包括設定、付費牆和空白狀態;最常見的失敗是有一個獨特的主頁,後面接著一堆標準的
Form。 - 圖像, 優先順序:專案自己的圖像;生成的圖像(如果你有圖片工具的話);來自開放素材庫的真實主題世界圖片,並記錄授權(
references/imagery.md);使用程式碼繪製(Shape、Canvas、Path),作為色版中一致的平面圖形語言;僅使用字體和顏色。SF Symbols 僅作為功能性圖示使用。 - 來自第 4 步驟的驚喜時刻,放在能夠證明其主張的畫面中。
- 充實度。 將每個畫面視為一張海報:一個主導元素及其所承載的內容。一個大部分是空白背景的畫面是建構不足的。正文應使用完整的文字色,字型大小為
body或更大。 - 框架。 一個統一的邊距系統。每個畫面都有一個標題(導覽標題或大型顯示標題),並且每個列表區塊都有一個命名它的區段標頭。
- 狀態與語意。 所有狀態:載入中、空白、錯誤、離線、權限拒絕、成功、停用、首次執行、長內容、輔助使用字型大小、從右至左書寫模式。實質的
Button、可見的焦點、標籤、僅在標籤無法承載時才使用的accessibilityHint、旁白順序、尊重減少動態效果與增加對比度。 - 平台基準(遵循全域規則):包含 en-US、en-GB、en-AU、en-CA 和 es-MX 的字串目錄;僅在正面體驗後使用
requestReview,並透過計數器和安裝天數來限制,每個版本一次;觸覺回饋;深色與淺色模式;在應用程式有核心操作時使用 App Intents。
當你需要做出某個決定背後的細節時,請閱讀 references/type.md、colour.md、layout.md 和 components.md;以下規則是簡化的版本。
7. 把關
node <skill>/scripts/lint.mjs <Swift 檔案或資料夾>
<skill>/scripts/capture.sh <bundle id> .taste-skill/capture # 已啟動的模擬器
lint.mjs 會掃描 Swift 原始碼中是否有被禁止的模式、陳腔濫調以及缺少的基準項目(字串目錄、減少動態效果、觸覺回饋)。capture.sh 會在每個已啟動的模擬器上,以淺色和深色模式、預設和輔助使用字型大小啟動已安裝的應用程式,並儲存螢幕截圖。修正每一個 FAIL;將每個 WARN 視為錯誤,除非你能用一句話向設計師解釋其合理性。重複執行直到沒有任何 FAIL。每一行程式碼都可以使用尾隨註解 // taste-skip-lint 來選擇性跳過檢查。
8. 評審
執行 taste-review 子命令(如果存在)或手動審查截圖。針對每個畫面,提出以下問題:
- 這個畫面是否承載著主題本身獨有的東西?
- 這個畫面是否依賴任何陳腔濫調(標準的引導頁順序、帶有發光效果的付費牆、四個分頁)?
- 排版是否大膽且不對稱?文字顏色與背景的對比度是否足夠?
- 色版是否源自主題,而不僅僅是美觀?
- 這個應用程式是否有一個只有在這個應用程式中才有意義的手勢或互動?
- 如果移除所有裝飾元素,這個畫面是否仍然有實質內容?
- 在輔助使用字型大小下,這個畫面是否仍然能正常運作?
- 這個應用程式是否感覺像屬於這個平台,而不是一個移植的網頁應用程式?
針對每個「否」的答案,記錄一個動作項目。在修正問題並通過所有檢查之前,不要將任何畫面標記為完成。