iOS 動態(tài)更新

App
動態(tài)更新
1、控件到 window的層級關(guān)系:
2、分析控件的詳細(xì)路徑:
3、動態(tài)修改控件:
4、工具篇:

視圖的層級關(guān)系:
每個 App , 至少有一個根 Window , 通常情況下我們只用一個 。window 有一個 rootViewController , 這就是我們所謂的根視圖 , 我們所有的控制器都是放在 rootViewController 里面的。

2114369369-562afc9b0a1ad_articlex.jpg

這個是最簡單的層級關(guān)系

如果在項(xiàng)目里有了這么一個路徑 , 我們可以做什么呢?
在當(dāng)項(xiàng)目很復(fù)雜 , 可以其它地方可以直接修改這個控件的狀態(tài)
當(dāng)某個控件命名存在卻又沒有顯示出來 , 可以通過路徑來輔助查找
由服務(wù)器下發(fā)一些配置 , 使用 Runtime
去動態(tài)的修改已上線的項(xiàng)目

下面將介紹如何使用代碼來找出這些視圖(控件)的路徑
分析控件的詳細(xì)路徑
1、找出根 Window
:
每一個視圖、控件 , 他們最終的根都是main函數(shù)返回的 application
, 通過 [UIApplication sharedApplication]
可以得到 。 application
的 windows
屬性是一個數(shù)組 , 這里面裝的是這個應(yīng)用的所有 Window
, 我們通常用的是第一個也就是 application.windows[0]

2、遍歷視圖 :
得到了 window
對象一切都好辦了 。 然后拿到 window
的 rootViewController
, 在獲取 rootViewController
里面所有的childViewControllers
和 view
里的 subviews
, 一直遞歸下去就可以得到當(dāng)前屏幕里所有視圖對象了 , 同時可以通過 runtime
把它們的property
、 delegate
都獲取出來 。結(jié)合 Reveal
或者 Xcode
自帶的 Captuer View Hiearachy
, 我們可以推測一下這兩個的的實(shí)現(xiàn)原理了 :1、根據(jù)應(yīng)用得到根視圖2、遞歸獲取里面的所有控件3、按照他們的層級關(guān)系一層一層的畫出來

動態(tài)修改控件
1、把上面獲取到的所有控件的詳細(xì)信息上傳到服務(wù)器 。2、根據(jù)業(yè)務(wù)需求由服務(wù)器給我們下發(fā)對應(yīng)的配置列表 , 以 button
為例 : 配置列表里必須要有 :
1)、button
的全路徑 : 如 UIWindow-> UIWindow-> UIView -> UIView -> UILayoutContainerView -> UITabBar -> UIView —>UIButton
2)、button
的唯一標(biāo)識 : 如 tag
值或自己實(shí)現(xiàn)的一套算法生成的唯一標(biāo)識 , 目的是防止與 button
同一層次的視圖搞混 。3)、 根據(jù)路徑及唯一標(biāo)識來匹配 App
里的控件 , 匹配和上面的查找原理是相通的。4)、 匹配成功代表 button
確實(shí)存在 , 根據(jù)業(yè)務(wù)需求做后續(xù)操作 。提示: 匹配策略盡可能的多 , 防止意外情況某一兩個標(biāo)識生成失敗或者生成相同 。

3、修改 button
的狀態(tài)。
1)、 如某個按鈕點(diǎn)了會 Crash
或暫時不需要被點(diǎn)擊 , 但是又要展示出來 , 可以直接修改 button
的 enabled
屬性 。2)、 如某業(yè)務(wù)暫時關(guān)閉 , 可以直接修改入口 按鈕
frame為0 , 前提是要自動布局已做好 。3)、 如給購買 按鈕
添加監(jiān)聽事件 addTarget: action: forControlEvents:
target
也可以通過上面 遍歷視圖
獲取到 , action
可以由服務(wù)器下發(fā) , 也可以一開始就寫死 , 等有需求的時候直接傳不同的參數(shù)就行了 。

4、 綁定查找控件時 , 這個界面必須要已經(jīng)初始化完成了才行 , 假如界面還沒生成肯定是查找不到這個控件的 。 這里給大家提供兩種思路 :
1、使用Runtime Method Swizzing
, 直接把修改控件的方法與 didMoveToSuperview
和 didMoveToWindow
動態(tài)綁定 , 等這個控件加載出來之后再去修改 , 查找路徑正確的話肯定就能找到了 。2、在具體的類里面 , 等控件的初始化方法調(diào)用完后 , 再去執(zhí)行動態(tài)修改 , 如在viewDidLoad
里面初始化控件 , 在 viewWillAppear:
里面動態(tài)修改 。建議使用第一種適用范圍更強(qiáng) 。

上架后的 應(yīng)用
可能會遇到的一些突發(fā)狀況 , 未測出的Crash
、臨時改點(diǎn)小需求 , 等等 , 我們總不能每次因?yàn)橐稽c(diǎn)小改動就重新提交一次 App Store
, 先不說 App Store
的審核時間 , 頻繁的讓用戶去更新應(yīng)用 , 用戶也會煩的 。使用這篇文章所講的來實(shí)現(xiàn)動態(tài)更新是再合適不過了 。  首先上面講的 動態(tài)更新
是完全脫離出來的一個模塊 , 跟業(yè)務(wù)邏輯沒有任何關(guān)系 , 只需要部署一次就行了 , 等開發(fā)下一個項(xiàng)目也可以直接拿過去使用 。這里的動態(tài)更新適用于局部的視圖、控件的修改 , 如果你有其它需求可以考慮 JSPatchwax , 下發(fā)腳本也是一個不錯的選擇 。
工具篇:
使用一些UI調(diào)試的輔助工具 , 使我們查看視圖在項(xiàng)目中得層次結(jié)構(gòu)更為方便 。常用的UI調(diào)試的工具:
Captuer View Hiearachy
Reveal

Xcode自帶的 Captuer View Hiearachy
實(shí)現(xiàn)步驟:
1、打開Xcode , 運(yùn)行項(xiàng)目 , 選擇最頂部的 Debug

2、Debug -> View Debugging -> Show View Frames

3、Debug -> View Debugging -> Captuer View Hiearachy

Xcode里面就變成了三維的視圖了 , Xcode左側(cè)展示出來的是層級關(guān)系的樹狀圖 。
Reveal的功能相對來說更強(qiáng)大 , 適用于UI調(diào)試視圖查找 。使用方法請看 Reveal集成指南

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,245評論 4 61
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,372評論 25 708
  • 一.load 的調(diào)用 load 方法會在加載類的時候就被調(diào)用,也就是 ios 應(yīng)用啟動的時候,就會加載所有的類,就...
    俊俊吖閱讀 568評論 1 0
  • 2017年1月5日,第五次打卡。 這兩天感冒了,早上起來涕淚橫流哇,好慘! 閑話不多說,上早餐:五色粥、蒸山藥、蒸...
    一粒薄荷糖閱讀 758評論 5 13
  • 存一寸光陰 換一個世紀(jì) 摘一片苦心 釀一滴蜂蜜 生活的儀式感與矯情無關(guān) 是我熱愛生活的方式 … ...
    cc大美人閱讀 272評論 1 2