2013/11/16

在 UIView 中和 UIButton 一樣設定背景


圖片元件來源:Designing Buttons in iOS 5

Hi, @vince78718 です

最近想在 UIView 中做出像 UIButton 一樣,可以用單一背景指定邊角寬度、拉伸開來成為整個按鈕的背景,原本想說完了,該不會又要手刻 UI library 來達成我的需求。

以前 iOS 比賽的 App 有遇到一樣的情形,最後有點偷懶,在 table view 的每一格 cells 用 CALayer 動態畫背景,下場就是非常非常吃資源,一滑過去一直卡一直卡,幾乎沒有辦法使用。

於是去 Google 一下有沒有解法,想必也有許多人想這樣做,於是就讓我找到了 ~~



廢話分隔線

UIButton 的做法

首先,根據之前找到的 "DESIGNING BUTTONS IN IOS 5" 這篇文章,除了直接用最簡單的方法,就是用 resizableImageWithCapInsets: 這個 UIImage 的 method 來指定想要使用的邊緣寬度。


另外,在 UIButton 宣告指定 UIButtonType 的時候請注意,在 iOS 7 中,原有的 UIButtonTypeRoundedRect 已經 deprecated ,請使用 UIButtonTypeSystem。通常需要向下支援,判斷裝置版本後再給予相對應的 type 。

本段相關 doc: resizableImageWithCapInsets:, buttonWithType:, UIButtonType


進到本篇主題

UIView 設定背景第一步

最原始的做法如下,由於 colorWithPatternImage: 的關係,就會發現背景被像棋盤般的排列,根本不是我想要的



本段相關 doc: colorWithPatternImage:


解法分隔線

把背景「畫」出來

接下來要準備一個「畫布」,就是 context,將背景的圖片根據設定的邊框寬度,繪製到指定大小(這邊是目標 UIView 的 frame 大小),再將結果轉為 UIImage 、包裝成 UIColor instance ,再指定為 UIView 的背景。


但是 ... 他是模糊的啊!明明有在 project 中有加 @2x 的圖片說 ...


左為模糊、右為清晰的圓角(這邊圓角半徑沒很大,大一點的話差異會更清楚)

本段相關 doc: UIGraphicsBeginImageContext


解決模糊分隔線

原因是 Retina !!

如果你不想支援 retina ,可以跳過這段沒關係(誤)。

在 iOS 坐標系統中是用 points 而非 pixels 。在 iOS 4.0 之後,因為 scale factor 的關係,在繪製的時候,非 retina 螢幕為 1.0(pt:px = 1:1) , retina 螢幕則是 2.0(pt:px = 1:2)。而 SDK 也給了方便的做法,當指定為 0.0f 的時候,就會自動使用該裝置的 scale factor。

因此,這裡的做法要稍微改變一下:將設定畫布的 UIGraphicsBeginImageContext 換成 UIGraphicsBeginImageContextWithOptions ,便多了第三個參數可以指定 scale factor。

而第二個參數則是設定 opaque (不透明),如果你的圖片有含有 alpha 層,請設定為 NO ,無則設定為 YES 。


破關領獎,開心回家

本段相關 doc: scale factor, UIGraphicsBeginImageContextWithOptions


破關分隔線

範例 Repo

Github: Page | Download
or clone me


取扱説明書

這個 repo 在主要的步驟有加上 !!! 註解,
可以在下拉的 method 清單看到,讓大家更容易觀看





Repo 分隔線

若是文章、 code 中有錯誤的地方、或是交流討論,歡迎電梯下樓留言指出
謝謝觀看、下次見~!


碎碎念分隔線

Reference

沒有留言:

張貼留言