介绍
支付宝有一个功能:当进入后台时,用户会看到一个毛玻璃效果的保护界面覆盖在应用之上,防止泄露敏感信息。当回到前台时,保护界面自动消失,用户看到正常的应用界面。本文将研究与实现该效果。
实现
思路
- 实现效果:在退到后台时,在界面再添加一层“毛玻璃界面”,在回到前台时移除该“毛玻璃界面”。
- 利用了 iOS 中退到后台与回到前台 2 个生命周期函数。
- 毛玻璃效果可以通过
UIVisualEffectView
实现。 - 毛玻璃界面需要能够覆载在最上面,可以通过
UIWindow
实现。
代码
- 主界面。
import UIKit
class ViewController: UIViewController {
lazy var label: UILabel = {
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 300, height: 50))
label.center = view.center
label.text = "敏感信息,后台不可查看"
label.font = .monospacedSystemFont(ofSize: 25, weight: .bold)
label.textAlignment = .center
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(label)
}
}
- 毛玻璃界面。
import UIKit
class PrivacyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
visualEffectView.frame = view.bounds
view.addSubview(visualEffectView)
}
}
- SceneDelegate 处理生命周期与 UIWindow。
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
// 增加一个新的隐私UIWindow
private var privacyWindow: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let _ = (scene as? UIWindowScene) else { return }
}
func sceneWillEnterForeground(_ scene: UIScene) {
// 隐藏
hidePrivacyWindow()
}
func sceneDidEnterBackground(_ scene: UIScene) {
// 显示
showPrivacyWindow()
}
// MARK: 创建并显示隐私UIWindow
private func showPrivacyWindow() {
guard let windowScene = window?.windowScene else {
return
}
privacyWindow = UIWindow(windowScene: windowScene)
// 切换rootViewController为隐藏敏感信息的UIViewController
privacyWindow?.rootViewController = PrivacyViewController()
// 将保护窗口置于最顶层
privacyWindow?.windowLevel = .alert + 1
privacyWindow?.makeKeyAndVisible()
}
// MARK: 隐藏隐私UIWindow
private func hidePrivacyWindow() {
privacyWindow?.isHidden = true
privacyWindow = nil
}
}