前言
项目中做的一个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。