前言
項目中做的一個Swift版本的翻牌動畫,在自定義Window
彈窗基礎上,使用transition
動畫實現。
效果圖
翻牌
1.彈窗部分
彈窗考慮到解耦和使用便捷,采取自定義Window
來實現,所有彈窗由一個可銷毀單例來統一管理,這樣可以很容易管理每個彈窗,也方便擴展其他類型的彈窗,當所有彈窗都全部銷毀后,單例自行銷毀
彈窗核心代碼
//MARK: - 彈窗管理者
@objcMembers class CLPopupManager: NSObject {
private static var manager: CLPopupManager?
private class var share: CLPopupManager {
get {
guard let shareManager = manager else {
manager = CLPopupManager()
return manager!
}
return shareManager
}
}
private var windowsDictionary = [String : CLPopupManagerWindow]()
private override init() {
super.init()
}
deinit {
// CLLog("===== \(self.classForCoder) deinit =====")
}
}
extension CLPopupManager {
/// 顯示自定義彈窗
private class func showController(_ controller: CLPopupManagerController) {
DispatchQueue.main.async {
if controller.configure.isDisplacement {
share.windowsDictionary.removeAll()
}
let window = CLPopupManagerWindow(frame: UIScreen.main.bounds)
window.isPassedDown = controller.configure.isPassedDown
window.windowLevel = UIWindow.Level.statusBar
window.isUserInteractionEnabled = true
window.rootViewController = controller
window.makeKeyAndVisible()
share.windowsDictionary[controller.configure.identifier] = window
}
}
/// 隱藏所有彈窗
class func dismissAll() {
DispatchQueue.main.async {
share.windowsDictionary.removeAll()
manager = nil
}
}
///隱藏指定彈窗
class func dismiss(_ identifier : String) {
DispatchQueue.main.async {
share.windowsDictionary.removeValue(forKey: identifier)
if share.windowsDictionary.isEmpty {
dismissAll()
}
}
}
}
2.動畫部分
動畫的核心采取系統transition
動畫實現,加上其他基礎動畫組合而成
func transition(withDuration duration: TimeInterval, completion: (() -> Void)?) {
guard let top = topView, let bottom = bottomView else {
return
}
if isTurning {
return
}
isTurning = true
if isReversed {
UIView.transition(from: bottom, to: top, duration: duration, options: .transitionFlipFromLeft) { _ in
completion?()
self.isTurning = false
self.isReversed = false
}
} else {
UIView.transition(from: top, to: bottom, duration: duration, options: .transitionFlipFromRight) { _ in
completion?()
self.isTurning = false
self.isReversed = true
}
}
}
3.其他彈窗
可拖拽彈窗
按鈕彈窗
總結
核心代碼已經貼出,完整代碼請查看----->>>CLDemo,如果對你有所幫助,歡迎Star。