How to display an activity indicator with text on iOS 8 with Swift?

前端 未结 14 2158
没有蜡笔的小新
没有蜡笔的小新 2020-11-27 08:58

I wanna show, programmatically, an activity indicator with text, like the one in the Photos app (after editing and saving a picture). How can I do this?

相关标签:
14条回答
  • 2020-11-27 09:46

    Based on "MirekE" answer here is a code that i tested now and its working:

    var activityIndicator: UIActivityIndicatorView!
    
    var viewActivityIndicator: UIView!
    
    override func viewDidLoad()
    {
        super.viewDidLoad()
    
        let width: CGFloat = 200.0
        let height: CGFloat = 50.0
        let x = self.view.frame.width/2.0 - width/2.0
        let y = self.view.frame.height/2.0 - height/2.0
    
        self.viewActivityIndicator = UIView(frame: CGRect(x: x, y: y, width: width, height: height))
        self.viewActivityIndicator.backgroundColor = UIColor(red: 255.0/255.0, green: 204.0/255.0, blue: 51.0/255.0, alpha: 0.5)
        self.viewActivityIndicator.layer.cornerRadius = 10
    
        self.activityIndicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
        self.activityIndicator.color = UIColor.blackColor()
        self.activityIndicator.hidesWhenStopped = false
    
        let titleLabel = UILabel(frame: CGRect(x: 60, y: 0, width: 200, height: 50))
        titleLabel.text = "Processing..."
    
        self.viewActivityIndicator.addSubview(self.activityIndicator)
        self.viewActivityIndicator.addSubview(titleLabel)
    
        self.view.addSubview(self.viewActivityIndicator)
    }
    
    func doSometing()
    {
        self.activityIndicator.startAnimating()
        UIApplication.sharedApplication().beginIgnoringInteractionEvents()
    
        //do something here that will taking time
    
        self.activityIndicator.stopAnimating()
        UIApplication.sharedApplication().endIgnoringInteractionEvents()
        self.viewActivityIndicator.removeFromSuperview()
    }
    
    0 讨论(0)
  • 2020-11-27 09:49
    import UIKit
    
    class ViewControllerUtils {
    
        let containerView: UIView = {
    
            let view = UIView()
            view.translatesAutoresizingMaskIntoConstraints = false
            view.backgroundColor = UIColor(white: 0, alpha: 0.3)
            return view
        }()
    
        let loadingView: UIView = {
    
            let view = UIView()
            view.translatesAutoresizingMaskIntoConstraints = false
            view.backgroundColor = UIColor(white: 0, alpha: 0.7)
            view.clipsToBounds = true
            view.layer.cornerRadius = 10
            return view
        }()
    
        let activityIndicatorView: UIActivityIndicatorView = {
    
            let aiv = UIActivityIndicatorView()
            aiv.translatesAutoresizingMaskIntoConstraints = false
            aiv.style = UIActivityIndicatorView.Style.whiteLarge
            return aiv
        }()
    
        let loadingLabel: UILabel = {
    
            let label = UILabel()
            label.translatesAutoresizingMaskIntoConstraints = false
            label.text = "Loading..."
            label.textAlignment = .center
            label.textColor = .white
            label.font = .systemFont(ofSize: 15, weight: UIFont.Weight.medium)
            return label
        }()
    
        func showLoader() {
    
            guard let window = UIApplication.shared.keyWindow else { return }
    
            window.addSubview(containerView)
            containerView.addSubview(loadingView)
            loadingView.addSubview(activityIndicatorView)
            loadingView.addSubview(loadingLabel)
    
            containerView.leftAnchor.constraint(equalTo: window.leftAnchor).isActive = true
            containerView.rightAnchor.constraint(equalTo: window.rightAnchor).isActive = true
            containerView.topAnchor.constraint(equalTo: window.topAnchor).isActive = true
            containerView.bottomAnchor.constraint(equalTo: window.bottomAnchor).isActive = true
    
            loadingView.centerXAnchor.constraint(equalTo: window.centerXAnchor).isActive = true
            loadingView.centerYAnchor.constraint(equalTo: window.centerYAnchor).isActive = true
            loadingView.widthAnchor.constraint(equalToConstant: 120).isActive = true
            loadingView.heightAnchor.constraint(equalToConstant: 120).isActive = true
    
            activityIndicatorView.centerXAnchor.constraint(equalTo: window.centerXAnchor).isActive = true
            activityIndicatorView.centerYAnchor.constraint(equalTo: window.centerYAnchor).isActive = true
            activityIndicatorView.widthAnchor.constraint(equalToConstant: 60).isActive = true
            activityIndicatorView.heightAnchor.constraint(equalToConstant: 60).isActive = true
    
            loadingLabel.leftAnchor.constraint(equalTo: loadingView.leftAnchor).isActive = true
            loadingLabel.rightAnchor.constraint(equalTo: loadingView.rightAnchor).isActive = true
            loadingLabel.bottomAnchor.constraint(equalTo: loadingView.bottomAnchor).isActive = true
            loadingLabel.heightAnchor.constraint(equalToConstant: 40).isActive = true
    
            DispatchQueue.main.async {
    
                self.activityIndicatorView.startAnimating()
            }
        }
    
        func hideLoader() {
    
            DispatchQueue.main.async {
    
                self.activityIndicatorView.stopAnimating()
                self.activityIndicatorView.removeFromSuperview()
                self.loadingLabel.removeFromSuperview()
                self.loadingView.removeFromSuperview()
                self.containerView.removeFromSuperview()
            }
        }
    }
    
    //// In order to show the activity indicator, call the function from your view controller
    // let viewControllerUtils = ViewControllerUtils()
    // viewControllerUtils.showLoader()
    
    //// In order to hide the activity indicator, call the function from your view controller
    // viewControllerUtils.hideLoader()
    
    class ViewControllerUtils2 {
    
        var container: UIView = UIView()
        var loadingView: UIView = UIView()
        var activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()
        let loadingLabel = UILabel()
    
        func showLoader(_ uiView: UIView) {
    
            container.frame = uiView.frame
            container.center = uiView.center
            container.backgroundColor = UIColor(white: 0, alpha: 0.3)
    
            loadingView.frame = CGRect(x: 0, y: 0, width: 120, height: 120)
            loadingView.center = uiView.center
            loadingView.backgroundColor = UIColor(white: 0, alpha: 0.7)
            loadingView.clipsToBounds = true
            loadingView.layer.cornerRadius = 10
    
            activityIndicator.frame = CGRect(x: 0, y: 0, width: 60, height: 60)
            activityIndicator.style = UIActivityIndicatorView.Style.whiteLarge
            activityIndicator.center = CGPoint(x: loadingView.frame.size.width / 2, y: loadingView.frame.size.height / 2)
    
            loadingLabel.frame = CGRect(x: 0, y: 80, width: 120, height: 40)
            loadingLabel.text = "Loading..."
            loadingLabel.textAlignment = .center
            loadingLabel.textColor = .white
            loadingLabel.font = .systemFont(ofSize: 15, weight: UIFont.Weight.medium)
    
            uiView.addSubview(container)
            container.addSubview(loadingView)
            loadingView.addSubview(activityIndicator)
            loadingView.addSubview(loadingLabel)
    
            DispatchQueue.main.async {
    
                self.activityIndicator.startAnimating()
            }
        }
    
        func hideLoader() {
    
            DispatchQueue.main.async {
    
                self.activityIndicator.stopAnimating()
                self.activityIndicator.removeFromSuperview()
                self.loadingLabel.removeFromSuperview()
                self.loadingView.removeFromSuperview()
                self.container.removeFromSuperview()
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-27 09:50

    This code work in SWIFT 2.0.

    Must Declare a variable for initialize UIActivityIndicatorView

    let actInd: UIActivityIndicatorView = UIActivityIndicatorView() 
    

    After initialize put this code in your controller.

    actInd.center = ImageView.center
    actInd.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.WhiteLarge
    view.addSubview(actInd)
    actInd.startAnimating()
    

    after your download process complete then hide a animation.

    self.actInd.stopAnimating()
    
    0 讨论(0)
  • 2020-11-27 09:52

    For Swift 3

    Usage

    class LoginTVC: UITableViewController {
        var loadingView : LoadingView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // CASE 1: To Show loadingView on load
    
            loadingView = LoadingView(uiView: view, message: "Sending you verification code")
        }
    
        // CASE 2: To show loadingView on click of a button
    
        @IBAction func showLoadingView(_ sender: UIButton) {
            if let loaderView = loadingView{ // If loadingView already exists
                if loaderView.isHidden() {
                    loaderView.show()  // To show activity indicator
                }
            }
            else{
                loadingView = LoadingView(uiView: view, message: "Sending you verification code")
             }
        }
    }
    
        // CASE 3: To hide LoadingView on click of a button
    
        @IBAction func hideLoadingView(_ sender: UIButton) {
            if let loaderView = loadingView{ // If loadingView already exists 
                self.loadingView.hide()   
            }
        }
    }
    

    LoadingView Class

    class LoadingView {
    
        let uiView          :   UIView
        let message         :   String
        let messageLabel    =   UILabel()
    
        let loadingSV       =   UIStackView()
        let loadingView     =   UIView()
        let activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
    
        init(uiView: UIView, message: String) {
            self.uiView     =   uiView
            self.message    =   message
            self.setup()
        }
    
        func setup(){
            let viewWidth   = uiView.bounds.width
            let viewHeight  = uiView.bounds.height
    
            // Configuring the message label
            messageLabel.text             = message
            messageLabel.textColor        = UIColor.darkGray
            messageLabel.textAlignment    = .center
            messageLabel.numberOfLines    = 3
            messageLabel.lineBreakMode    = .byWordWrapping
    
            // Creating stackView to center and align Label and Activity Indicator
            loadingSV.axis          = .vertical
            loadingSV.distribution  = .equalSpacing
            loadingSV.alignment     = .center
            loadingSV.addArrangedSubview(activityIndicator)
            loadingSV.addArrangedSubview(messageLabel)
    
            // Creating loadingView, this acts as a background for label and activityIndicator
            loadingView.frame           = uiView.frame
            loadingView.center          = uiView.center
            loadingView.backgroundColor = UIColor.darkGray.withAlphaComponent(0.3)
            loadingView.clipsToBounds   = true
    
            // Disabling auto constraints
            loadingSV.translatesAutoresizingMaskIntoConstraints = false
    
            // Adding subviews
            loadingView.addSubview(loadingSV)
            uiView.addSubview(loadingView)
            activityIndicator.startAnimating()
    
            // Views dictionary
            let views = [
                "loadingSV": loadingSV
            ]
    
            // Constraints for loadingSV
            uiView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-[loadingSV(300)]-|", options: [], metrics: nil, views: views))
            uiView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-\(viewHeight / 3)-[loadingSV(50)]-|", options: [], metrics: nil, views: views))
        }
    
        // Call this method to hide loadingView
        func show() {
            loadingView.isHidden = false
        }
    
        // Call this method to show loadingView
        func hide(){
            loadingView.isHidden = true
        }
    
        // Call this method to check if loading view already exists
        func isHidden() -> Bool{
            if loadingView.isHidden == false{
                return false
            }
            else{
                return true
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-27 09:54

    Heres how this code looks:

    enter image description here

    Heres my drag and drop code:

    var boxView = UIView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    
        view.backgroundColor = UIColor.blackColor()
        addSavingPhotoView()
    
        //Custom button to test this app
        var button = UIButton(frame: CGRect(x: 20, y: 20, width: 20, height: 20))
        button.backgroundColor = UIColor.redColor()
        button.addTarget(self, action: "buttonAction:", forControlEvents: UIControlEvents.TouchUpInside)
    
        view.addSubview(button)
    }
    
    func addSavingPhotoView() {
        // You only need to adjust this frame to move it anywhere you want
        boxView = UIView(frame: CGRect(x: view.frame.midX - 90, y: view.frame.midY - 25, width: 180, height: 50))
        boxView.backgroundColor = UIColor.whiteColor()
        boxView.alpha = 0.8
        boxView.layer.cornerRadius = 10
    
        //Here the spinnier is initialized
        var activityView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray)
        activityView.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
        activityView.startAnimating()
    
        var textLabel = UILabel(frame: CGRect(x: 60, y: 0, width: 200, height: 50))
        textLabel.textColor = UIColor.grayColor()
        textLabel.text = "Saving Photo"
    
        boxView.addSubview(activityView)
        boxView.addSubview(textLabel)
    
        view.addSubview(boxView)
    }
    
    func buttonAction(sender:UIButton!) {
        //When button is pressed it removes the boxView from screen
        boxView.removeFromSuperview()
    }
    

    Here is an open source version of this: https://github.com/goktugyil/CozyLoadingActivity

    0 讨论(0)
  • 2020-11-27 09:54

    With auto width and theme support also detects rotate while busy (Swift 3 version)

    Use it like below:

    var progressView: ProgressView?
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        self.progressView = ProgressView(message: "Work in progress!",
                                             theme: .dark,
                                             isModal: true)
    }
    
    @IBAction func onPause(_ sender: AnyObject) {
        self.progressView.show()      
    }
    
    @IBAction func onResume(_ sender: AnyObject) {
        self.progressView.hide()       
    }
    

    ProgressView.swift

    import UIKit
    
    class ProgressView: UIView {
    
        enum Theme {
            case light
            case dark
        }
    
        var theme: Theme
        var container: UIStackView
        var activityIndicator: UIActivityIndicatorView
        var label: UILabel
        var glass: UIView
    
    
        private var message: String
        private var isModal: Bool
    
        init(message: String, theme: theme, isModal: Bool) {
            // Init
            self.message = message
            self.theme = theme
            self.isModal = isModal
    
            self.container = UIStackView()
            self.activityIndicator = UIActivityIndicatorView()
            self.label = UILabel()
            self.glass = UIView()
    
            // Get proper width by text message
            let fontName = self.label.font.fontName
            let fontSize = self.label.font.pointSize
            if let font = UIFont(name: fontName, size: fontSize) {
                let fontAttributes = [NSFontAttributeName: font]
                let size = (message as NSString).size(attributes: fontAttributes)
                super.init(frame: CGRect(x: 0, y: 0, width: size.width + 50, height: 50))
            } else {
                super.init(frame: CGRect(x: 0, y: 0, width: 200, height: 50))
            }
    
            // Detect rotation
            NotificationCenter.default.addObserver(self, selector: #selector(onRotate), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
    
            // Style
            self.layer.cornerRadius = 3
            if (self.theme == .dark) {
                self.backgroundColor = .darkGray
            } else {
                self.backgroundColor = .lightGray
            }
    
            // Label
            if self.theme == .dark {
                self.label.textColor = .white
            }else{
                self.label.textColor = .black
            }
            self.label.text = self.message
            // Container
            self.container.frame = self.frame
            self.container.spacing = 5
            self.container.layoutMargins = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
            self.container.isLayoutMarginsRelativeArrangement = true
            // Activity indicator
            if (self.theme == .dark) {
                self.activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .whiteLarge)
                self.activityIndicator.color = .white
            } else {
                self.activityIndicator = UIActivityIndicatorView(activityIndicatorStyle:.whiteLarge)
                self.activityIndicator.color = .black
            }
            self.activityIndicator.startAnimating()
            // Add them to container
    
            // First glass
            if let superview = UIApplication.shared.keyWindow {
                if (self.isModal) {
                    // glass
                    self.glass.frame = superview.frame;
                    if (self.theme == .dark) {
                        self.glass.backgroundColor = UIColor.black.withAlphaComponent(0.5)
                    } else {
                        self.glass.backgroundColor = UIColor.white.withAlphaComponent(0.5)
                    }
                    superview.addSubview(glass)
                }
            }
            // Then activity indicator and label
            container.addArrangedSubview(self.activityIndicator)
            container.addArrangedSubview(self.label)
            // Last attach it to container (StackView)
            self.addSubview(container)
            if let superview = UIApplication.shared.keyWindow {
                self.center = superview.center
                superview.addSubview(self)
            }
            //Do not show until show() is called
            self.hide()
        }
    
        required init(coder: NSCoder) {
            self.theme = .dark
            self.Message = "Not set!"
            self.isModal = true
            self.container = UIStackView()
            self.activityIndicator = UIActivityIndicatorView()
            self.label = UILabel()
            self.glass = UIView()
            super.init(coder: coder)!
        }
    
        func onRotate() {
            if let superview = self.superview {
                self.glass.frame = superview.frame
                self.center = superview.center
    //            superview.addSubview(self)
            }
        }
    
        public func show() {
            self.glass.isHidden = false
            self.isHidden = false
        }
    
        public func hide() {
            self.glass.isHidden = true
            self.isHidden = true
        }
    }
    
    0 讨论(0)
提交回复
热议问题