最近使用了一下 IBAnimatable,這個庫對 IBInspectable
的使用真讓人歎為觀止。突然意識到其實 IBInspectable
可以讓我們減少很多不必要的重復代碼。對一個 UIView
進行描邊是我們在開發過程中比較常用的,UI 設計師們希望通過描邊來增加界面的層次感。
在剛開始做 iOS 開發時,我很喜歡使用這樣的方式。但後來發現這種實現用一下兩個缺點:
後期如果 UI 需要重新調整,會變得比較痛苦。
一般描邊都只需要1個像素的描邊,在使用 Xib
或 StoryBoard
的時候需要設置 0.5 這樣的值。Xib
和 StoryBoard
好像支持的不太好,經常會出現在 plus 上描邊的線看起來特別粗。
這個方法實現描邊的效果很不錯。但還是有些缺點:
有些 UIView
其實在代碼中不需要體現,但因為需要描邊。我必須把它拖到代碼中。
代碼中到處出現,進行描邊的代碼,一定程度影響代碼的美觀和閱讀性(PS: 我有潔癖)。
對這些實現進行封裝的確是一個不錯的選擇。但我也許還有可能有更好的方案。
這裡我只描述我的實現思路,不對 IBInspectable
進行介紹。畢竟 IBInspectable
是 2014WWDC 的內容了(PS: 比我學習 iOS 還要早 = =),很多大神都有博客對其介紹。
喵神的 WWDC 2014 Session筆記 - 可視化開發,IB 的新時代
Nate Cook 的 IBInspectable / IBDesignable(譯文)
思路如下:
可以使用 IBDesignable
將屬性定義到 IB 中,通過定義屬性,實現描邊。
我們可以統一在 layoutSubviews
中進行描邊處理。
我不希望為了實現描邊還去繼承一個類,所以我選擇對 UIView
通過 Category
實現描邊的功能。
我需要增加一下新的屬性來定義描邊,所以我需要使用 AssociatedObject
實現。對於 AssociatedObject
不了解的同學可以看南峰子的這篇博客 Objective-C Runtime 運行時之二:成員變量與屬性。
由於我希望通過 Category
實現描邊,我還需要使用 Method Swizzling
實現。在每個 UIView
及其子類 在實現 layoutSubviews
去執行我的描邊代碼。不了解的同學可以看南峰子的這篇博客 Objective-C Runtime 運行時之四:Method Swizzling。
如圖,只需要在 IB 上配置上屬性,就可以實現描邊的功能。
這樣做還是有缺點的,IB 上的屬性有點多。。。
對於代碼感興趣的同學可以到https://github.com/bay2/IBViewExt,我在這裡就不貼代碼了,代碼不多看 UIView+IB.m
文件就可以了。
BDesignable
和 IBInspectable
無法在 Cocoa Touch Frameworks 中生效,詳細看這裡,所以使用 Carthage
的時候,BDesignable
和 IBInspectable
也無法正常工作, cocoapods
不會有次問題。
BDesignable
無法再 categories/extensions 正常工作, stackoverflow 上也有提到這個問題