Thousand Squared

希望能分享一些學習心得啊啊啊~~~.

PasscodeLock

| Comments

前陣子實作了 PasscodeLock ,感覺還蠻有趣的,跟大家分享如何實作。

一個好的 PasscodeLock 要能夠蓋住全部的UI,像是 UIAlertView, UIActionSheet,或者是 UIImagePickerController

但利用一般的 UIViewController 是做不到的,因為 UIAlertView 的顯示層級最高。因此要利用另外一種方法來實作PasscodeLock─UIWindow

實作UIWindow

View source on Github

PasscodeLock的關鍵就是:要建立另一個UIWindow。

為什麼呢?

因為 UIAlertView、UIActionSheet 等這些 View 其實都會建立自己的 UIWindow,也因為這樣,這些 UIAlertView 才可以顯示在最上層。 所以當你看到 UIAlertView 時,它跟原本的 app 畫面已經在不同層次(也就是不同 UIWindow)了。所以無論你在原本的 viewController 怎麼寫,都沒有辦法覆蓋在 UIAlertView 上。

要覆蓋住 UIAlertView,只能夠建立一個 Level 比他高的 UIWindow。
以下是建立的程式碼:

1
2
3
4
5
6
self.window = [[[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds] autorelease];

//set window level
self.window.windowLevel = UIWindowLevelAlert + 2;

self.window.rootViewController = passcodeLockViewController;

重點在設定 window level

把這些值印出來就可以知道,UIWindowLevelAlert 是最大的:

1
2
3
2013-01-27 22:41:04.744 PasscodeLock[28036:c07] >>>>>>>>>>UIWindowLevelAlert 2000.000000
2013-01-27 22:41:04.745 PasscodeLock[28036:c07] >>>>>>>>>>UIWindowLevelStatusBar 1000.000000
2013-01-27 22:41:04.745 PasscodeLock[28036:c07] >>>>>>>>>>UIWindowLevelNormal 0.000000

因此我們只要設定一個比 UIWindowLevelAlert 大的值就可以了,但有沒有副作用我就不知道了XD

另外就是顯示的時候啦,有兩個部分:

第一個部分是在:

1
2
3
4
- (void) applicationDidEnterBackground:(UIApplication*) application
{
  [self.passcodeLockWindow show];
}

為什麼要寫在這裡?因為當一進入背景的時候,就要先建立好 PasscodeLock,根據 Document 表示

When an app transitions to the background, the system takes a snapshot of the app’s main window, which it then presents briefly when transitioning your app back to the foreground.

上面說的是 App 進入背景時,系統會先截圖。等到 app 再次開啟時,就可以秀出這張截圖作為Loading時使用。

為了避免看到未上鎖的畫面,在 app 進入背景時就先建立好 PasscodeLock 並顯示,等到下次開啟 app 時,就可以直接看到 PasscodeLock 的畫面。

第二個部分在:

1
2
3
4
- (BOOL) application:(UIApplication*) application didFinishLaunchingWithOptions:(NSDictionary*) launchOptions
{
  [self.passcodeLockWindow show];
}

初次開啟 app 時,就要啟動 PasscodeLock。

有了這兩個地方就可以控制 PasscodeLock 的出現與消失。

實作Keyboard

另一個部分就是實作 Keyboard ,為什麼要自己實作 Keyboard?

因為有特例要處理,假設情境如下:

當你開啟密碼鎖並且在更改密碼時,突然有人打電話近來。
等你講完電話後,開啟app,此時要輸入密碼解鎖,輸入完後會跳到更改密碼的畫面。

如果此時都是用原生的 Keyboard,在 iOS4 與 iOS5+ 會有不一樣的情況發生,因為 Keyboard 要在不同 UIWindow 出現。而原生的 Keyboard 是 Singlton的東西,處理起來會有一些問題。
因此在整體效率及維護的考量之下,使用假鍵盤是最佳解(我自己覺得XD)!

How to use this project

1. 建立PasscodeLock畫面

因此當你需要設定密碼、更改密碼、驗證密碼時需要繼承:

AbstractPasscodeLockViewController,其中有1個重要的 method 需要實作

1
- (void) onFilled:(NSString*) result

當填滿密碼時,就會呼叫此 method,需要在此 method 判斷密碼是否正確。

2. 呼叫 PasscodeLock Window

class PasscodeLockWindow 用來建立、顯示與隱藏 PasscodeLock window。

要建立此 instance 來操作 PasscodeLock。

小結

這是最基本的PasscodeLock,還可以加上動畫、特效讓他看起來更炫。

那如果忘記密碼呢?

很抱歉,只能重新安裝App啦XDD,不然你也可以寫一個暗鎖解開他(譬如案10次0)。

View source on Github

Comments