iOS如何使用OperationQueue实现弹框依次展示

大家都知道,在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.
    }


}

 

 

Leave a Reply

Your email address will not be published.