弹框简介
在我们日常开发中,经常遇到 UI 设计的各种弹框,如:登录页面、加载、提示框、悬浮球等等
系统自带的 UIAlertController ,往往满足不了我们的要求,但是我们有需要这种效果,那该怎么做呢?
如下几种方法解决:
在 VC 里面添加 alertView,然后 show in keyWindow
自定义modal Transition,类似 UIAlertController
创建另外一个 window 来显示弹框
通过 modal Transition 实现 Alert
具体大家可以参考 iOS 视图控制器转场详解
UIWindow方式添加弹框
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| class WindowAlert: UIViewController { private lazy var alertWindow: UIWindow = { var window = UIWindow(frame: UIScreen.main.bounds) if #available(iOS 13.0, *) { let windowScene = UIApplication.shared.connectedScenes.filter { $0.activationState == .foregroundActive }.first if let windowScene = windowScene as? UIWindowScene { window = UIWindow(windowScene: windowScene) } } window.windowLevel = UIWindow.Level.alert - 1 window.backgroundColor = .clear return window }()
private lazy var backgroundView: UIView = { let v = UIView() v.backgroundColor = UIColor.black.withAlphaComponent(0.2) v.isUserInteractionEnabled = true let tap = UITapGestureRecognizer(target: self, action: #selector(dismissAlert)) v.addGestureRecognizer(tap) return v }() private lazy var contentView: UIView = { let v = UIView() v.backgroundColor = .white return v }() override func viewDidLoad() { super.viewDidLoad() view.addSubview(self.backgroundView) view.addSubview(self.contentView) } override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() self.backgroundView.frame = view.bounds self.contentView.frame = CGRect(x: (view.frame.width - 200) / 2, y: (view.frame.height - 250) / 2, width: 200, height: 250) } init(title: String, message: String) { super.init(nibName: nil, bundle: nil) } public func show() { alertWindow.isHidden = false alertWindow.rootViewController = self backgroundView.alpha = 0.0 contentView.transform = CGAffineTransform(scaleX: 1.1, y: 1.1) UIView.animate(withDuration: 0.25, delay: 0, options: .curveEaseOut, animations: { [unowned self] () in self.backgroundView.alpha = 1.0 self.contentView.transform = CGAffineTransform.identity }, completion: nil) } public func dismiss() { UIView.animate(withDuration: 0.15, delay: 0, options: .curveEaseOut, animations: { [unowned self] () in self.contentView.alpha = 0.0 self.backgroundView.alpha = 0.0 }) { (_) in self.alertWindow.isHidden = true self.alertWindow.rootViewController = nil } } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } @objc dynamic func dismissAlert() { dismiss() }
}
|
学习代码
1、HSActionSheet:objc,仿微信 ActionSheet,在一个自定义 UIViewController 在另一个 window 上显示,回调用 block 和 delegate
2、WXActionSheet:swift,功能比较全的 ActionSheet,自定义UIView 在当前 keyWindow 上显示,回调用 closure
3、PPSActionSheet:objc,功能单一的 ActionSheet,实现思路与WXActionSheet 类似
4、SPAlertController:objc,功能很全包括 alert 和 ActionSheet,以 modal 转场的方式来实现,具体其简书也有介绍
5、FWPopupView:objc/swift,支持AlertView、Sheet、自定义视图的PopupView
6、QiShare/QiToast