談不完美的IBDesignable/IBInspectable視覺化效果程式設計

發表於2016-07-29

我們好像慢慢地習慣了“理想很豐滿,現實很骨感”這樣順序這樣的轉折這樣常態,那麼如果是“現實很豐滿,理想很骨感”,我們能接受嗎?現實豐滿可以,但是理想很骨感那就不要將就了。就像薛之謙希望是能通過“醜八怪 呀啊呀啊呀哎呀”來唱紅的自己,而不是上綜藝做直男直到沒朋友的諧星來笑紅自己卻跟他的歌關係不大。

蘋果開發中使用的XCode也有這樣的“現實豐滿,理想骨感”例子,蘋果公司在2011年就推出了UIStoryboard技術,到現在已經6年了。蘋果還不在xcode的Interface Builder上直接提供修改控制元件的圓角,邊框設定,而是提供IBDesignable/IBInspectable這樣的技術讓這些重複簡單的工作由開發者來實現圓角外框,最後category上使用IBDesignable/IBInspectable卻不能直接現實想要的結果。

那邊我們來體驗一下薛之謙的“人紅歌不紅”的“現實很豐滿,理想很骨感”感覺。

111252638-f37440d4434ac6ce

文章思維導圖.png

一.我們想要很簡單

在Storyboard中的所有控制元件能通過Interface builder直接設定最基本圓角,邊框和邊框顏色屬性,表達理想的Storyboard能顯示出我要的渲染效果,而不是編寫程式碼後只能在執行在手機或模擬器時才出現我們想要的效果。就像薛之謙想通唱歌紅了自己,簡單明瞭。

二.基本概念

  1. IB_DESIGNABLE的巨集的功能就是讓XCode動態渲染出該類圖形化介面。UIView 或 NSView使用IB_DESIGNABLE巨集宣告時候,就是讓Interface Builder知道它應該在UIStoryboard或者Xib中畫布上直接渲染檢視,不需要等到編譯執行後就能預先展示出來效果 。
  2. IBInspectable修飾屬性,可以是使用者自定義的執行時屬性,讓支援KVC的屬效能夠在Attribute Inspector中配置。

三.使用方式

1.IB_DESIGNABLE放在@interface或者@implement都可以,申明這個類在XCode直接看到渲染的效果。

2.IBInspectable 修飾屬性,使屬效能在XCode中直接設定。**

四 .普通類繼承關係實現渲染效果

根據第三所列出的2個關鍵點,詳細具體實現:

1.自定義IBDesignableImageView 繼承UIImageView。

2.接著在IBDesignableImageView.m檔案實現下set方法

3.接著,XCode中Customer Class選擇IBDesignableImageView。

4.最後,interface builder屬性欄中設定你剛剛屬性。

121252638-b5fa0f97509f2a0c

類繼承關係實現效果圖

主要就是以上四步基本滿足一下下storyboard成功展示一種View實時渲染效果的快感,猶如薛之謙嘗試到一首《醜八怪》火一陣子,爽一陣子的快感,並且不會讓人誤認為這是趙全的《我很醜可是我很溫柔》的續本。

五.UIView的Category實現渲染效果

嚐到了好處,自然想到實現通用的方式給需要控制元件都加上interface builder可設定相關屬性。所以,我們自認為UIView其他子View父類,那麼如果UIView可是直接在XCode上設定屬性實現渲染,那麼其他子View隨之得到渲染效果。

1.我們最想看到的結果是

我們最想看到結果是,UIImageView、UITextField、UIButton等等都能如願的被interface builder直接修改相關圓角,邊框等等屬性。噔噔,我們腦海浮現以下畫面:

131252638-bb7efcdd94eef870

最理想狀態

2.編寫UIView的Category類UIView+MGO.h

3.編寫UIView+MGO.m中的實現

這個.m的實現類,有幾個知識點要注意:
1).category中新增IBInspectable修飾屬性,必須帶有set和get的方法,不然編譯都通過。
2).KVC觀察屬性值變化,從而得到即時重新整理效果。
3).category中自定義屬性如上邊defineValue屬性,使用runtime方式賦值。所以會有objc_setAssociatedObject(self, @selector(defineValue), @(defineValue),OBJC_ASSOCIATION_ASSIGN);這樣的程式碼。_defineValue = defineValue;這樣也是行,這樣是有語法問題的。
詳細的runtime和KVC知識點可以檢視《談Runtime機制和使用的整體化梳理》《談KVC、KVO(重點觀察者模式)機制程式設計》

4.在interface builder設定相關屬性

1).屬性欄可以看可設定圓角,邊框寬度等

141252638-123b5012da33d253

設定UIView(MGO定義出來屬性)

2).Runtime Attribute欄中也能自動生成剛剛設定的屬性值

151252638-d64f673e368515d2
Runtime Attribute顯示屬性值

5.檢視storyboard上的頭像有沒有顯示設定的屬性值

161252638-e0d549d1519f0d7a

UIView(MGO)展示的效果

Oh。。。my god!storyboard上一點效果也沒顯示出來,反而模擬器執行效果確實理想的狀態。活生生的“現實很豐滿,理想很骨感”表現得淋漓盡致。難道要硬著頭皮瞬間退回到解放前,重複不斷的寫繼承程式碼。。。打死也不,,,告訴你淘寶發過來的驗證碼!

六.曲線救國處理Category不顯示效果問題

曲線救國生活中可以,國就是救那麼一兩次,沒國了也沒辦法。程式中,每時每刻都在救國,明擺著這欺負人嘛!不過,國我們還是得救的,歌薛之謙還是要唱的,先找到兩者的微妙關係,串成曲線才行。於是乎,薛之謙將段子手的頭銜發揮到極致,參加各大綜藝,《火星情報站》《極限挑戰》《大學生來了》等等,趁機唱唱“醜八怪 呀啊呀啊哎呀”,道理就明瞭了,就是死活出現在人面前晃來晃去。
喲,那會不會interface builder死活要看到UIView的自定義子類的繼承類,設定在Customer Class中才行啊。試試?

1.編寫一個 空白MGOImageView繼承UIImageView。

2.MGOImageView.m檔案什麼也不幹,就是等機會對接UIView(MGO)自定義屬性。

3.選中storyboard中的UIImageView在Customer Class選擇 MGOImageView。

171252638-35836a69e7bf6e2c

編寫空白MGOImageView嘗試

噢,,,了個天啊!storyboard上一點效果都沒有少顯示出來,反而嚇到了現實中的我。那就趁熱吃豆腐了,把其他控制元件都寫一個對應空白的子類,設定在customer class上。

181252638-bb27de25bd3a6028

其他控制元件都新增對應的子類

好像幸福就是來得那麼突然,傷心的小船說翻就翻了。會不會有更大幸福,於是乎,小明在google上搜尋“IBDesignable/IBInspectable在Category中沒有效果”。看了兩三頁搜尋結果,最後比較接近的是Cocachina中也有一個沒有人回覆的相關帖子,和另外一篇跟我的發現一樣要寫一個空白的子類設定在Customer Class 中才行。

七.對比總結

經過以上一系列折騰,最後的結果確認令我覺得“不完美的IBDesignable/IBInspectable”。有些對XCode,Storyboard專案者有些一丁點的期待外,同時也是希望有開發者提供更好的處理方式。對比其他IDE,,就算了。追求完美我們是天生的,盡情開發我們也是認真的。

八.原始碼下載

https://github.com/minggo620/iOSDesignable.git
好想要到薛之謙的微信,向他發1毛錢的紅包,然後他會一如既往地回“不好意思,我不收別人的微信紅包”,接著我收到了200塊紅包。

【原創出品 未經授權 禁止轉載】
【歡迎微友分享轉發 禁止公號等未經授權的轉載】

191252638-7a68bcc2b2ec9939

微信公眾號:minggo_dev

相關文章