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

前端 未结 14 2157
没有蜡笔的小新
没有蜡笔的小新 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:57

    While Esq's answer works, I've added my own implementation which is more in line with good component architecture by separating the view into it's own class. It also uses dynamic blurring introduced in iOS 8.

    Here is how mine looks with an image background:

    enter image description here

    The code for this is encapsulated in it's own UIView class which means you can reuse it whenever you desire.

    Updated for Swift 3

    Usage

    func viewDidLoad() {
      super.viewDidLoad()
    
      // Create and add the view to the screen.
      let progressHUD = ProgressHUD(text: "Saving Photo")
      self.view.addSubview(progressHUD)
      // All done!
    
      self.view.backgroundColor = UIColor.black
    }
    

    UIView Code

    import UIKit
    
    class ProgressHUD: UIVisualEffectView {
    
      var text: String? {
        didSet {
          label.text = text
        }
      }
    
      let activityIndictor: UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
      let label: UILabel = UILabel()
      let blurEffect = UIBlurEffect(style: .light)
      let vibrancyView: UIVisualEffectView
    
      init(text: String) {
        self.text = text
        self.vibrancyView = UIVisualEffectView(effect: UIVibrancyEffect(blurEffect: blurEffect))
        super.init(effect: blurEffect)
        self.setup()
      }
    
      required init?(coder aDecoder: NSCoder) {
        self.text = ""
        self.vibrancyView = UIVisualEffectView(effect: UIVibrancyEffect(blurEffect: blurEffect))
        super.init(coder: aDecoder)
        self.setup()
      }
    
      func setup() {
        contentView.addSubview(vibrancyView)
        contentView.addSubview(activityIndictor)
        contentView.addSubview(label)
        activityIndictor.startAnimating()
      }
    
      override func didMoveToSuperview() {
        super.didMoveToSuperview()
    
        if let superview = self.superview {
    
          let width = superview.frame.size.width / 2.3
          let height: CGFloat = 50.0
          self.frame = CGRect(x: superview.frame.size.width / 2 - width / 2,
                          y: superview.frame.height / 2 - height / 2,
                          width: width,
                          height: height)
          vibrancyView.frame = self.bounds
    
          let activityIndicatorSize: CGFloat = 40
          activityIndictor.frame = CGRect(x: 5,
                                          y: height / 2 - activityIndicatorSize / 2,
                                          width: activityIndicatorSize,
                                          height: activityIndicatorSize)
    
          layer.cornerRadius = 8.0
          layer.masksToBounds = true
          label.text = text
          label.textAlignment = NSTextAlignment.center
          label.frame = CGRect(x: activityIndicatorSize + 5,
                               y: 0,
                               width: width - activityIndicatorSize - 15,
                               height: height)
          label.textColor = UIColor.gray
          label.font = UIFont.boldSystemFont(ofSize: 16)
        }
      }
    
      func show() {
        self.isHidden = false
      }
    
      func hide() {
        self.isHidden = true
      }
    }
    

    Swift 2

    An example on how to use it is like this:

    override func viewDidLoad() {
        super.viewDidLoad()
    
        // Create and add the view to the screen.
        let progressHUD = ProgressHUD(text: "Saving Photo")
        self.view.addSubview(progressHUD)
        // All done!
    
        self.view.backgroundColor = UIColor.blackColor()
    }
    

    Here is the UIView code:

    import UIKit
    
    class ProgressHUD: UIVisualEffectView {
    
        var text: String? {
            didSet {
                label.text = text
            }
        }
        let activityIndictor: UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.White)
        let label: UILabel = UILabel()
        let blurEffect = UIBlurEffect(style: .Light)
        let vibrancyView: UIVisualEffectView
    
        init(text: String) {
            self.text = text
            self.vibrancyView = UIVisualEffectView(effect: UIVibrancyEffect(forBlurEffect: blurEffect))
            super.init(effect: blurEffect)
            self.setup()
        }
    
        required init(coder aDecoder: NSCoder) {
            self.text = ""
            self.vibrancyView = UIVisualEffectView(effect: UIVibrancyEffect(forBlurEffect: blurEffect))
            super.init(coder: aDecoder)
            self.setup()
    
        }
    
        func setup() {
            contentView.addSubview(vibrancyView)
            vibrancyView.contentView.addSubview(activityIndictor)
            vibrancyView.contentView.addSubview(label)
            activityIndictor.startAnimating()
        }
    
        override func didMoveToSuperview() {
            super.didMoveToSuperview()
    
            if let superview = self.superview {
    
                let width = superview.frame.size.width / 2.3
                let height: CGFloat = 50.0
                self.frame = CGRectMake(superview.frame.size.width / 2 - width / 2,
                    superview.frame.height / 2 - height / 2,
                    width,
                    height)
                vibrancyView.frame = self.bounds
    
                let activityIndicatorSize: CGFloat = 40
                activityIndictor.frame = CGRectMake(5, height / 2 - activityIndicatorSize / 2,
                    activityIndicatorSize,
                    activityIndicatorSize)
    
                layer.cornerRadius = 8.0
                layer.masksToBounds = true
                label.text = text
                label.textAlignment = NSTextAlignment.Center
                label.frame = CGRectMake(activityIndicatorSize + 5, 0, width - activityIndicatorSize - 15, height)
                label.textColor = UIColor.grayColor()
                label.font = UIFont.boldSystemFontOfSize(16)
            }
        }
    
        func show() {
            self.hidden = false
        }
    
        func hide() {
            self.hidden = true
        }
    }
    

    I hope this helps, please feel free to use this code wherever you need.

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

    Xcode 10.1 • Swift 4.2

    import UIKit
    
    class ProgressHUD: UIVisualEffectView {
    
        var title: String?
        var theme: UIBlurEffect.Style = .light
    
        let strLabel = UILabel(frame: CGRect(x: 50, y: 0, width: 160, height: 46))
        let activityIndicator = UIActivityIndicatorView()
    
        init(title: String, theme: UIBlurEffect.Style = .light) {
            super.init(effect: UIBlurEffect(style: theme))
    
            self.title = title
            self.theme = theme
    
            [activityIndicator, strLabel].forEach(contentView.addSubview(_:))
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
        override func didMoveToSuperview() {
            super.didMoveToSuperview()
    
            if let superview = self.superview {
                frame = CGRect(x: superview.frame.midX - strLabel.frame.width / 2,
                               y: superview.frame.midY - strLabel.frame.height / 2, width: 160, height: 46)
    
                layer.cornerRadius = 15.0
                layer.masksToBounds = true
    
                activityIndicator.frame = CGRect(x: 0, y: 0, width: 46, height: 46)
                activityIndicator.startAnimating()
    
                strLabel.text = title
                strLabel.font = .systemFont(ofSize: 14, weight: UIFont.Weight.medium)
    
                switch theme {
                case .dark:
                    strLabel.textColor = .white
                    activityIndicator.style = .white
                default:
                    strLabel.textColor = .gray
                    activityIndicator.style = .gray
                }
            }
    
        }
    
        func show() {
            self.isHidden = false
        }
    
        func hide() {
            self.isHidden = true
        }
    }
    

    Use:

    let progress = ProgressHUD(title: "Authorization", theme: .dark)
    [progress].forEach(view.addSubview(_:))
    
    0 讨论(0)
提交回复
热议问题