Пока происходит существующее представление перехода, стек навигации не будет обновлен - PullRequest
0 голосов
/ 23 декабря 2018

Я рассмотрел подобный вопрос здесь, в stackoverflow, но ни одно из решений не работает для меня.

Я выполняю сетевой вызов и на основании ответа на вызов я выполню навигацию.Для правильного интерфейса мне нужно показать диалог загрузки, чтобы показать пользователю, что что-то происходит.Поскольку мой диалог загрузки будет использоваться несколько раз, поэтому я создал расширение, подобное этому

import UIKit
extension UIViewController {

     func showLoadingDialog() {

        var alertController: UIAlertController!
        alertController = UIAlertController(title: nil, message: "Please wait...", preferredStyle: .alert)
        //alertController.view.tintColor = brownColor //UIColor.brown

        let loadingIndicator: UIActivityIndicatorView = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50)) as UIActivityIndicatorView
        loadingIndicator.hidesWhenStopped = true
        loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.white
        loadingIndicator.color = UIColor.white
        loadingIndicator.startAnimating()

        alertController.view.addSubview(loadingIndicator)
        alertController.view.subviews.first?.backgroundColor = UIColor.clear
        present(alertController, animated: false, completion: nil)

    }

    func dismissLoader() {
        dismiss(animated: false, completion: nil)
    }


func showToast(controller: UIViewController, message : String, seconds: Double) {
    let toastLabel = UILabel(frame: CGRect(x: 10, y: self.view.frame.size.height-100, width: self.view.frame.size.width-20, height: 50))
    toastLabel.backgroundColor = UIColor.black.withAlphaComponent(0.6)
    toastLabel.textColor = UIColor.white
    toastLabel.textAlignment = .center;
    toastLabel.font = UIFont(name: "Montserrat-Light", size: 12.0)
    toastLabel.text = message
    toastLabel.numberOfLines = 2
    toastLabel.alpha = 1.0
    toastLabel.layer.cornerRadius = 10;
    toastLabel.clipsToBounds  =  true
    self.view.addSubview(toastLabel)
    UIView.animate(withDuration: 3, delay: 1, options: .curveEaseOut, animations: {
        toastLabel.alpha = 0.0
    }, completion: {(isCompleted) in
        toastLabel.removeFromSuperview()
    })
}
}

Перед выполнением сетевого вызова я вызываю метод showLoadingDialog (), и когда я получаю ответ, я вызываю dismissLoader() метод, чтобы скрыть диалоговое окно загрузки, а затем на основе ответа я выполняю навигацию, как это

Это мой протокол просмотра, который реализуется моим контроллером

protocol ShipmentDetailsView: class {

    func setShipmentResponse(shipmentResponse: ShipmentResponse)

    func showErrorMessage(message: String)

    func showProgressDialog()

    func hideProgressDialog()

    func getShipmentId() -> String

    func navigateToLogin()

    func onStatusCheckSuccess(shipmentResponse: ShipmentResponse)

}

Это мойКонтроллер ...

import UIKit

class ShipmentDetailsViewController: UIViewController, ShipmentDetailsView{

    @IBOutlet weak var shipmentNumber: UILabel!
    @IBOutlet weak var siteName: UILabel!
    @IBOutlet weak var currentDestination: UILabel!
    @IBOutlet weak var address: UILabel!
    @IBOutlet weak var name: UILabel!
    @IBOutlet weak var phoneNumber: UILabel!
    @IBOutlet weak var startShipmentButton: UIButton!


    var viewController: UIViewController!
    var shipmentId: String = ""
    var shipmentResponse: ShipmentResponse!

    var presenter: IShipmentDetailsPresenter!

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        hideKeyboard()
    }

    private func onCreate() {
        presenter = ShipmentDetailsPresenter(view: self)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        onCreate()
    }

    @IBAction func startShipment(_ sender: Any) {
        presenter.getShipmentByIdToCheckStatus(shipmentId: self.shipmentId)
    }

    public func setShipmentId(shipmentId: String) {
        self.shipmentId = shipmentId
    }

    func navigateToLogin() {
        //Todo
    }

    func onStatusCheckSuccess(shipmentResponse: ShipmentResponse) {
        if shipmentResponse.Status == 0 {
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let verifyViewController = storyboard.instantiateViewController(withIdentifier: "RunningShipmentViewController") as! RunningShipmentViewController
            self.navigationController?.pushViewController(verifyViewController, animated: true)

        } else {
            showToast(controller: self, message: "Cannot start this shipment", seconds: 0.5)
        }
    }

    func getShipmentId() -> String {
        return self.shipmentId
    }

    func showErrorMessage(message: String) {
        showToast(controller: self, message: message, seconds: 1.0)
    }

    func showProgressDialog() {
        showLoadingDialog()
    }

    func hideProgressDialog() {
        dismissLoader()
    }

    func setShipmentResponse(shipmentResponse: ShipmentResponse) {
        self.shipmentResponse = shipmentResponse
        updateUI(shipmentResponse: shipmentResponse)
    }

    private func updateUI(shipmentResponse: ShipmentResponse) {
        if shipmentResponse.ShipmentNumber != "" {
            self.shipmentNumber.text = shipmentResponse.ShipmentNumber
        } else {
            self.shipmentNumber.text = "-"
        }

        if shipmentResponse.SiteName != "" {
            self.siteName.text = shipmentResponse.SiteName
        } else {
            self.siteName.text = "-"
        }

        if shipmentResponse.DestinationName != "" {
            self.currentDestination.text = shipmentResponse.DestinationName
        } else {
            self.currentDestination.text = "-"
        }

        if shipmentResponse.SiteAddress != "" {
            self.address.text = shipmentResponse.SiteAddress
        } else {
            self.address.text = "-"
        }

        if shipmentResponse.OrgResponsiblePersonName != "" {
            self.name.text = shipmentResponse.OrgResponsiblePersonName
        } else {
            self.name.text = "-"
        }

        if shipmentResponse.OrgResponsiblePersonPhone != "" {
            self.phoneNumber.text = shipmentResponse.OrgResponsiblePersonPhone
        } else {
            self.phoneNumber.text = "-"
        }
    }


}

Это мой код докладчика:

class ShipmentDetailsPresenter : IShipmentDetailsPresenter, ILoadShipmentInteractorOutput {


    var view: ShipmentDetailsView!
    var loadShipmentInteractor : ILoadShipmentInteractor!

    init(view: ShipmentDetailsView) {
        self.view = view
    }

    func getShipmentByIdToCheckStatus(shipmentId: String) {
        view.showProgressDialog()
        let queryString = NSString(format:Queries.SELECT_SHIPMENT_BY_ITEM_ID_QUERY as NSString, shipmentId)
        loadShipmentInteractor = LoadShipmentInteractor(loadShipmentInteractorOutput: self)
        loadShipmentInteractor.getShipmentByItemIdToCheckStatus(queryString: queryString as String)
    }

    func onGetShipmentByItemIdToCheckStatus(response: BaseResponse) {
        view.hideProgressDialog()
        if response.statusCode == 200 {
            if let json = response.response.data(using: .utf8){
                guard let obj = try? JSONDecoder().decode(ShipmentsResponse.self, from: json) else {return}
                if obj.StatusCode == 0 && obj.TotalRecordCount>0 {
                    view.onStatusCheckSuccess(shipmentResponse: obj.Results[0])
                } else {
                    //Todo
                }
            } else {
                let errMessage = NSLocalizedString("error_parsing_response", comment: "Message to show if parsing went wrong")
                print(errMessage)
            }

        } else if response.statusCode == 400 {
            view.showErrorMessage(message: Messages.SESSION_EXPIRED_MESSAGE)
            view.navigateToLogin()
        } else {
            view.showErrorMessage(message: Messages.SOMETHING_WENT_WRONG_MESSAGE)
            //view.navigateToLogin()
        }
    }

}

Вот мой интерактор:

import Alamofire

class LoadShipmentInteractor : ILoadShipmentInteractor {

    var loadShipmentInteractorOutput : ILoadShipmentInteractorOutput!

    init(loadShipmentInteractorOutput : ILoadShipmentInteractorOutput) {
        self.loadShipmentInteractorOutput = loadShipmentInteractorOutput
    }

    func getShipmentByItemIdToCheckStatus(queryString: String) {
        let accessToken : String = UserDefaultsUtil.getAccessToken()
        let url = ""+HttpRequestURLs.DATA_CORE_GET_FILTER
        let headers = [
            "Content-Type": Constatns.CONTENT_TYPE_JSON,
            "Authorization": "bearer "+accessToken
        ]

        let parameters = ["Text":queryString] as [String : Any]

        Alamofire.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseString {
            response in
            let statusCode = response.response?.statusCode as! Int
            let re = response.result.value as! String
            //print(re)
            let baseResponse = BaseResponse()
            baseResponse.statusCode = statusCode
            baseResponse.response = re
            self.loadShipmentInteractorOutput.onGetShipmentByItemIdToCheckStatus(response: baseResponse)
        }
    }

}
...