Tweaks::Facebook
Tweaks 是由 Facebook 三天前(約2014.3.25)所發佈的一套用於協助 prototyping 的框架。
在進行 App 的視覺設計時,最準確的方式就是:將 App 佈署到行動裝置上,並且實際在各種場合下進行各種操作。
什麼叫「各種場合」?
例如:
一套支援計步健身的 App,其色彩設計上的規劃必須考慮使用者在大太陽之下能不能看得清楚?
以銀髮族為角色的 App,其字體大小的最小尺寸、以及不會破壞排版的最大尺寸為多少?
App 內的動畫播放速度要多快不會太擔誤使用者的時間?但是又能看得清楚、得到預想的效果?
什麼叫「各種操作」?
例如:
對於單手持握裝置的使用者而言,App 內提供的按鈕位置是否容易觸發?是否操作旅行的路徑最短?
上述需求,可能會引起的因應動作是:開發者得不斷在程式碼/設定檔中調整各項參數,然後再一次進行至行動裝置的佈署及執行。顯然,有點花時間,對吧?而且,決定視覺設計的人,也可能不是程式開發者本身,這樣一來,要確定哪一個參數合適的過程中的溝通成本就不低。
Tweaks 可以讓上述情境 smooth 一些。
我從 FBTweakExample 中的程式碼來進行解釋。
一、FBTweakValue
_rootViewController.view.backgroundColor = [UIColor colorWithRed:0.9
green:0.9
blue:0.9
alpha:1.0];
上面的程式碼設定了 root 這個視圖控制器所管理的視圖的背景色,以RGB & Alpha 值進行設定。
改寫成下方 statement :
_rootViewController.view.backgroundColor =
[UIColor colorWithRed:FBTweakValue(@"Window", @"Color", @"Red", 0.9, 0.0, 1.0)
green:FBTweakValue(@"Window", @"Color", @"Green", 0.9, 0.0, 1.0)
blue:FBTweakValue(@"Window", @"Color", @"Blue", 0.9, 0.0, 1.0) alpha:1.0];
[UIColor colorWithRed:FBTweakValue(@"Window", @"Color", @"Red", 0.9, 0.0, 1.0)
green:FBTweakValue(@"Window", @"Color", @"Green", 0.9, 0.0, 1.0)
blue:FBTweakValue(@"Window", @"Color", @"Blue", 0.9, 0.0, 1.0) alpha:1.0];
這裡使用了 FBTweakValue 。是什麼意思呢?我們直接來看輸出:
第一個畫面是由 Tweaks 這個框架所提供的 (FBTweakViewController)。請注意看到第一個畫面中的「Window」row 和第二畫面中的「COLOR」session,請對應於上面程式碼中 FBTweakValue 的第一、第二個參數。而第二畫面中的 Red 就是對應第三個參數。我想大家也能猜出:第四個參數就是「預設值 0.9」。第五、第六個參數是最小值和最大值。
也就是說:只要我們將程式裡的某個值 (value) 代換成 FBTweakValue 這個 macro 的話,在 FBTweakViewController 啟動後就會把前三項參數產生為第一畫面列表中的一個列 (UITableViewCell)、第二畫面中的分段(Section) 及 分段 中的列。
以此例來說,提供了浮點數型別的三個數字作為第4~6個參數,FBTweakViewController 會自動生成 step 元件(兩個按鈕,一個減一個加)。
我們可以透過點按 step 元件來改變顏色的RGB值。
要注意的一點是:設定完之後,要把 App 先從背景移除後再開啟,該值才會生效。什麼?不能直接生效嗎?可以,不過得換個 macro 來用:FBTweakBind。
二、FBTweakBind
_label.text = @“Tweaks”;
上方的程式碼中,把標籤 _label 的文字設定為 Content。我們以下方的程式進行改寫:
FBTweakBind(_label, text, @"Content", @"Text", @"String", @"Tweaks");
第一個參數是 UI 元件,第二個參數則是該元件的屬性。第三 ~ 五個參數…直接看圖吧…,第六個參數則為預設值。
可以看出來,第三~五個參數是怎麼被產生出設定用的 UI 元件的。
這裡因為用的是 FBTweakBind 這個 macro ,所以值被變更的同時,回到 App 去看的話,就能馬上看到效果的變化。
三、FBTweakInline
上面提及的兩個 macro 有個共同之處:都是和某個 UI 元件的特定屬性相關。透過 FBTweakInline 可以用觀察者模式對某個設定項的值進行偵測,並於該值改變時調整 App 內任何的設定參數(不綁特定 UI 元件)。直接看實例吧:
_flipTweak = FBTweakInline(@"Window", @"Effects", @"Upside Down", NO);
[_flipTweak addObserver:self];
- (void)tweakDidChange:(FBTweak *)tweak
{
if (tweak == _flipTweak) {
_window.layer.sublayerTransform = CATransform3DMakeScale(1.0, [_flipTweak.currentValue boolValue] ? -1.0 : 1.0, 1.0);
}
}
畫面上的 EFFECTS -> Upside Down 預設值為 NO,並由程式碼的 host class 作為觀察者。只要 Upside Down 的值發者變化,則 call-back method : tweakDidChange 會被呼叫,然後就可以在該 method 內指定 App 要因應做何改變了(此範例是把螢幕轉180度,變成上下顛倒)。
以上就是 FBTweakExample 中和 FBTweaks 框架有關的示範了。
結語:
1. 可以用於 App 的設計階段。假設 coder 運用地夠純熟,大概不會太影響開發速度;UI designer 可以自行透過介面做各項參數的調整而不需要一再和 coder 反複針對單一參數進行溝通。
2. FBTweakExample 的寫法是為了容易說明,不過在程式碼中嵌入 FBTweak macro 時也會對程式碼 intention 的表達有影響:閱讀流暢度會受影響。要有更好的封裝:同時也得防止封裝影響偵錯。
3. 用於 Production … 嗯…持保留態度。
4. 可以看出這套框架應該能減少 UI design 及 coder 之間的溝通成本,這個應該很合適以不斷修正體驗設計的開發團隊。對於 UI design 及 program develop 流程分開且 one-step 執行 (non-iteration) 的團隊則不適用。