大家都知道,在iOS中,每个vc只能同时展示一个AlertController。
即如果不消掉正在展示的AlertController,是无法展示下一个AlertController的。
在不破坏这个原则的前提下,我们可以使用(NS)OperationQueue,来实现 弹框的串行展示。
首先是DelayedOperation,它对Operation做了一个简单的Hack,支持延迟结束Operation,结束时候调用下finisheOperation即可。
import Foundation class DelayedOperation: Operation { // MARK: - Override isExecuting and isFinished fileprivate var _isExecuting: Bool = false override var isExecuting: Bool { get { return _isExecuting } set { willChangeValue(forKey: "isExecuting") _isExecuting = newValue didChangeValue(forKey: "isExecuting") } } fileprivate var _isFinished: Bool = false override var isFinished: Bool { get { return _isFinished } set { willChangeValue(forKey: "isFinished") _isFinished = newValue didChangeValue(forKey: "isFinished") } } // MARK: - Funtions func finishOperation() { isExecuting = false isFinished = true } override func start() { isExecuting = true run() } /// Subclass should override this func run() { } }
接下来是主要的Operation类,它用于完成弹框的展示。
class AlertControllerOperation: DelayedOperation { fileprivate var seqId: Int fileprivate weak var parentVC: UIViewController? init(_ seq: Int, _ vc: UIViewController) { seqId = seq parentVC = vc super.init() } override func run() { let vc = UIAlertController(title: "Test", message: "Message", preferredStyle: .alert) vc.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in self.finishOperation() NSLog("DelayedOperation finished seq=%zd", self.seqId) DispatchQueue.main.asyncAfter(deadline: .now() + 3, execute: { self.finishOperation() }) })) parentVC?.present(vc, animated: true, completion: nil) } }
调用方法:
// // ViewController.swift // AlertControllerQueueDemo // // Created by Heyuan Li on 2017/5/22. // Copyright © 2017年 Heyuan Li. All rights reserved. // import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let q = OperationQueue() q.maxConcurrentOperationCount = 1 for i in 0...5 { let op = AlertControllerOperation(i, self) /* if i == 4 { op.queuePriority = .veryHigh } */ q.addOperation(op) } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }