iOS 一個(gè)實(shí)用的懸浮球工具

前言

已經(jīng)很久沒有寫文章了,前面寫過一篇 關(guān)于 UIWindow 的文章,在文章的最后提過懸浮球。用 UIWindow 來做懸浮球,可以懸浮在任意頁面,基于這個(gè)特性,我將其做成了一個(gè)工具,用在我們的項(xiàng)目開發(fā)中,今天把它作為主角來講一講。

先上代碼 → ZYSuspensionView GitHub 傳送門

為什么會(huì)有它

想要指定執(zhí)行一些代碼

在做公司項(xiàng)目的時(shí)候,可能會(huì)有這樣的情況,我需要在第一個(gè)進(jìn)某個(gè)頁面的時(shí)候彈出一些東西,簡(jiǎn)單做法,可能就會(huì)再、在 NSUserDefaults 中記錄一個(gè)值,表明彈出過??赡芪业谝淮螐棾鲋笥忠恍﹩栴},我改了代碼,運(yùn)行工程,重新進(jìn)頁面讓它彈出,可是卻彈不出來了,因?yàn)橐呀?jīng)標(biāo)記為彈出過,把包刪了,重運(yùn)行工程即可。

testmanager.gif

不過有了懸浮球,我通過點(diǎn)擊懸浮球,彈出一個(gè)列表,列表中每個(gè) cell 對(duì)應(yīng)我預(yù)先寫好的一些常用代碼,例如清除 NSUserDefaults 所有鍵值對(duì)等等,然后就達(dá)到了想要的效果。當(dāng)然這個(gè)比喻有很多槽點(diǎn),不過就這樣吧,不糾結(jié)。

真實(shí)用例如下,希望對(duì)你有點(diǎn)啟發(fā):

  1. 通過手動(dòng)插入一條的指定體重體脂率的體重?cái)?shù)據(jù)

    我們公司做體脂秤,所以開發(fā)的時(shí)候經(jīng)常需要這么做,不然就得光著腳在秤上稱,還不一定是自己想要的數(shù)值

  2. 清除 NSUserDefaults,讓包里的標(biāo)記干凈得像初戀一樣

  3. 顯示 log

    有時(shí)候測(cè)試人員測(cè)試的時(shí)候,發(fā)現(xiàn)頁面的 bug,可能我們?cè)谟行?case 預(yù)留了一些 log,但是想要導(dǎo)出就麻煩一些,通過點(diǎn)懸浮球列表的某個(gè) cell 跳轉(zhuǎn)到一個(gè)顯示 log 的頁面,快捷方便

  4. 顯示當(dāng)前賬號(hào)的 user id 及其他信息

    我們需要經(jīng)常查當(dāng)前賬號(hào)信息

  5. 跳轉(zhuǎn)到指定頁面

    正在開發(fā)某個(gè)頁面,需要依賴工程里的東西,所以在工程里開發(fā),但是還沒有開發(fā)完,由于入口深,每次改了一些東西重新跑工程還得點(diǎn)幾下,麻煩。修改 app 首頁的某個(gè)按鈕點(diǎn)擊事件,直接點(diǎn)擊進(jìn)入也不合適,影響正式代碼,而且容易忘記改回來。

  6. 其他一些雜七雜八的...

不想每次都輸入賬號(hào)密碼

因?yàn)轫?xiàng)目的原因,很多功能展示都和當(dāng)前賬號(hào)的數(shù)據(jù)有關(guān)系,所以想要自測(cè)自己的功能是否 OK,就需要頻繁切換賬號(hào),以保證每種情況都是真實(shí) cover 到了。

loginmanager.gif

用懸浮球,彈出一個(gè)賬號(hào)菜單,點(diǎn)擊自己想要登陸的賬號(hào),直接自動(dòng)登陸,媽媽再也不用擔(dān)心我每天都要輸入幾百次密碼了。 ???

好用嗎?怎么用?

個(gè)人感覺還是很好用了,為自己開發(fā)省去了不少時(shí)間,同時(shí)也為測(cè)試同學(xué)省去不少麻煩(有點(diǎn)自賣自夸的性質(zhì)了哈 ??)。頁面簡(jiǎn)單樸素,就是懸浮球 + 一個(gè)列表,咱不整那些虛的,主要就是實(shí)用。好不好用,試試就知道了。

我已經(jīng)將這個(gè)懸浮球做成了一個(gè) Pod 庫,公司的項(xiàng)目用了近一年了,穩(wěn)定,暫未發(fā)現(xiàn)有什么問題,如有 bug 可以給我提 issue。

這個(gè)組件主要分為個(gè)部分

  • SuspensionView
  • TestManager
  • LoginManager

SuspensionView 就是單純一個(gè)懸浮球,可以單獨(dú)集成。

TestManager

TestManager 是一個(gè)單例,將你預(yù)先寫好的代碼塊保存好,然后通過點(diǎn)擊懸浮列表的某個(gè) cell 執(zhí)行相應(yīng)代碼塊。

使用的時(shí)候,一般分為兩個(gè)部分:

一些是常駐的一些測(cè)試代碼,例如展示 log,清除 user defaults 等...

NSArray *baseArray = @[
                       @{
                           kTestTitleKey: @"clean user defaults",
                           kTestAutoCloseKey: @YES,
                           kTestActionKey: ^{
                               NSLog(@"click 'clean user defaults'");
                               [self cleanUserDefaults];
                           }
                           },
                       @{
                           kTestTitleKey:@"something",
                           kTestAutoCloseKey: @NO,
                           kTestActionKey:^{
                               NSLog(@"click 'something'");
                           }
                           },
                       ];
    
[ZYTestManager setupPermanentTestItemArray:baseArray];
  • kTestTitleKey 是測(cè)試條目的名字
  • kTestAutoCloseKey 為點(diǎn)擊該條目之后是否自動(dòng)關(guān)閉懸浮列表
  • kTestActionKey 很顯然,這就是點(diǎn)擊之后想要執(zhí)行的代碼

當(dāng)然,一些不常用的測(cè)試代碼,可能就是你突發(fā)奇想要跳轉(zhuǎn)到某個(gè)頁面,但是不影響項(xiàng)目的其他功能正常運(yùn)行,就可以使用另一個(gè)方法

[ZYTestManager addTestItemWithTitle:@"new item" autoClose:YES action:^{
    // click new item : do something ~~~~~~~~~~
}];

這里需要說明一些,傳入 block 的時(shí)候,如果用到 self,最好使用 __weak,避免影響到你正常功能,畢竟 TestManager 是一個(gè)單例。

LoginManager

LoginManager 顧名思義,就是拿來做自動(dòng)登錄的,同樣,點(diǎn)擊 login 懸浮球,彈出賬號(hào)列表,再點(diǎn)擊對(duì)于 cell,LoginManager 會(huì)回調(diào)給你儲(chǔ)存好的這個(gè)賬號(hào)的賬號(hào)和密碼。

- (void)loginManager:(ZYLoginManager *)loginManager loginWithAccout:(NSString *)account password:(NSString *)password
{
    // 這里去實(shí)現(xiàn)你的自動(dòng)登錄
}

可能你會(huì)說,自動(dòng)登錄都是我實(shí)現(xiàn)了,拿你還有什么用呢。LoginManager 做了如下事情:

  • 幫你存儲(chǔ)賬號(hào)密碼
  • 列表展示你預(yù)先設(shè)置或者登錄過的賬號(hào),并通過你的點(diǎn)擊回調(diào)給你

自動(dòng)登錄的代碼是不可能幫你做好的,因?yàn)槊總€(gè)工程里的與登錄對(duì)于的代碼完全不同,不可能通用,所以,咱只能做到這一步了,哈哈哈。不過這里還是給你提供了一個(gè)獲取當(dāng)前控制器的方法,可以直接使用

UIViewController *currentVC = [ZYLoginManager currentViewControllerWithWindow:nil];

其實(shí)自動(dòng)登錄無非就是兩步

  1. 獲取當(dāng)前控制器,查看是否為登錄的控制器
  2. 如果是,利用 performSelector 調(diào)用登錄部分的代碼

如果不是登錄的控制器怎么辦呢?一般的 app,在沒有登錄的時(shí)候一般第一個(gè)頁面就是登錄頁面,或者點(diǎn)擊一下某個(gè)按鈕,跳轉(zhuǎn)到登錄頁面,其實(shí)獲取當(dāng)前控制器的時(shí)候,完全可以判斷是否為第一個(gè)頁面,如果是,就 performSelector 跳轉(zhuǎn)到登錄頁面,再在登錄頁面 performSelector 調(diào)用登錄部分的代碼。根據(jù)不同情況再做一些調(diào)整吧。

除了是實(shí)現(xiàn)這個(gè)方法,你還需要做兩件事情:

  • 告訴我你登錄成功了,并且告訴我是哪個(gè)賬號(hào),我這時(shí)候需要隱藏登錄的懸浮球,并且為你保存賬號(hào)
[[NSNotificationCenter defaultCenter] postNotificationName:@"kZYLoginSuccessNotificationKey"
                                                    object:@{account:password}];
  • 告訴我你退出登錄了,我需要重新展示登錄按鈕,方便下一次自動(dòng)登錄
[[NSNotificationCenter defaultCenter] postNotificationName:@"kZYLogoutSuccessNotificationKey"
                                                    object:nil];

安全嗎?

這東西,能跟著上線嗎,不小心蹦出來個(gè)懸浮球給用戶看到那不是尷尬了。不能攜帶上線的話,每次上線還得刪除,多麻煩啊。?? 這個(gè)大可放心,我已經(jīng)帶著它上線了 n 個(gè)版本了,而且?guī)缀跛写a我都加上了

#if DEBUG
...
#endif

所以根本不需要擔(dān)心,只要工程改為 release 模式運(yùn)行壓根就出現(xiàn)不了懸浮球,里面的代碼根本也不會(huì)執(zhí)行。

我的建議是像我 demo 里面那樣,寫一個(gè) config 類,將上面所有常用的測(cè)試代碼和測(cè)試賬號(hào)都寫在這里類里面,放在一起,將污染做到最小。如果你這樣做了,在這里 config 類的 setup 方法再加上一個(gè) #if DEBUG,你會(huì)發(fā)現(xiàn) TestManagerLoginManager 這兩個(gè)單例對(duì)象根本就不會(huì)初始化,還有什么可擔(dān)心的。

基本就這么多吧,如果你覺得有用的話,請(qǐng)不要吝嗇你的 star?? 哦!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,741評(píng)論 25 709
  • 我們總是怪時(shí)光過的太快,可我們想過為什么時(shí)光過的那么快呢,有兩種,一種是把時(shí)光用在了有用的地方,另一種呢? 把時(shí)光...
    三歲的晴小晴閱讀 208評(píng)論 0 0
  • 這一日 天氣甚好 特意寄一箋書 千里之外與你相邀 這一日 畫眉梳妝 腰身一扭 嬌媚十足 踏馬而來的你 看一眼就此生...
    露露小公主閱讀 285評(píng)論 0 1

友情鏈接更多精彩內(nèi)容