Search code examples
iosswiftuiviewconstraintsautoresizingmask

center an indicator view in an alertcontroller programmatically


I am trying to center an activity indicator in an alert controller programmatically but am not seeing the expected outcome.

Attempt:

import NVActivityIndicatorView

public func displayActivityAlertWithCompletion(ViewController: UIViewController, pending: UIAlertController, completionHandler: @escaping ()->())
{

    //create an activity indicator
    let indicator = NVActivityIndicatorView(frame: CGRect(x: (pending.view.frame.width/2) - 25 , y: 0, width: 50, height: 50))


    //indicator.clipsToBounds = true
    indicator.type = .ballScaleMultiple
    indicator.autoresizingMask = \[.flexibleWidth, .flexibleHeight\]
    indicator.color = UIColor(rgba: Palette.loadingColour)



    //add the activity indicator as a subview of the alert controller's view
    pending.view.addSubview(indicator)
    indicator.isUserInteractionEnabled = false
    // required otherwise if there buttons in the UIAlertController you will not be able to press them
    indicator.startAnimating()



    ViewController.present(pending, animated: true, completion: completionHandler)
}

enter image description here


Solution

  • The problem you are facing lies in this line:

    let indicator = NVActivityIndicatorView(frame: CGRect(x: (pending.view.frame.width/2) - 25 , y: 0, width: 50, height: 50))
    

    At this point your pending alert controller is not yet presented, and it's frame is not updated.

    You will have to update the frame of the indicator after the alert controller was presented, so for example you can do the following.

    Replace this line:

    ViewController.present(pending, animated: true, completion: completionHandler)
    

    With this:

    ViewController.present(pending, animated: true, completion: {
        // update frame here:
        indicator.frame = CGRect(x: (pending.view.frame.width/2) - 25 , y: 0, width: 50, height: 50)
        // and manually call completionHandler:
        completionHandler()
    })