Display activity indicator inside UIButton

后端 未结 10 1707
囚心锁ツ
囚心锁ツ 2021-01-31 17:36

I would like to change the content of a UIButton to an ActivityIndicator after it is pressed.

I know buttons have an imageView and a titleLabel, but I don\'t know how to

相关标签:
10条回答
  • 2021-01-31 18:10

    Swift 5, Xcode 11.3

    I've modified it for my use case to include the button text, together with the spinner

    import UIKit
    
    class LoadingButton: UIButton {
    
    var activityIndicator: UIActivityIndicatorView!
    
    let activityIndicatorColor: UIColor = .gray
    
    func loadIndicator(_ shouldShow: Bool) {
        if shouldShow {
            if (activityIndicator == nil) {
                activityIndicator = createActivityIndicator()
            }
            self.isEnabled = false
            self.alpha = 0.7
            showSpinning()
        } else {
            activityIndicator.stopAnimating()
            self.isEnabled = true
            self.alpha = 1.0
        }
    }
    
    private func createActivityIndicator() -> UIActivityIndicatorView {
        let activityIndicator = UIActivityIndicatorView()
        activityIndicator.hidesWhenStopped = true
        activityIndicator.color = activityIndicatorColor
        return activityIndicator
    }
    
    private func showSpinning() {
        activityIndicator.translatesAutoresizingMaskIntoConstraints = false
        self.addSubview(activityIndicator)
        positionActivityIndicatorInButton()
        activityIndicator.startAnimating()
    }
    
    private func positionActivityIndicatorInButton() {
        let trailingConstraint = NSLayoutConstraint(item: self,
                                                   attribute: .trailing,
                                                   relatedBy: .equal,
                                                   toItem: activityIndicator,
                                                   attribute: .trailing,
                                                   multiplier: 1, constant: 16)
        self.addConstraint(trailingConstraint)
    
        let yCenterConstraint = NSLayoutConstraint(item: self,
                                                   attribute: .centerY,
                                                   relatedBy: .equal,
                                                   toItem: activityIndicator,
                                                   attribute: .centerY,
                                                   multiplier: 1, constant: 0)
        self.addConstraint(yCenterConstraint)
    }
    
    }
    

    If you're using storyboard, ensure that your button is of type LoadingButton (do this on your storyboard as well as view controller file, otherwise it'll crash)

    @IBOutlet weak var myButton: LoadingButton!
    

    and to use it,

    myButton.loadIndicator(true)
    

    0 讨论(0)
  • 2021-01-31 18:11

    Another solution for Swift4, I tried to make it simpler than previous solutions. This Extension allows you to resize the UIActivityIndicatorView (scale) to make fit inside the UIButton, and change the color.

    https://gist.github.com/jalopezsuarez/0ecc885b3fd5c555630799a067d66d98

    import Foundation
    import UIKit
    
    class UIButtonActivity: UIButton {
    
        @IBInspectable var indicatorColor : UIColor = .lightGray
    
        private var buttonLabel: String?
    
        func startAnimating() {
            self.isEnabled = false
    
            buttonLabel = self.titleLabel?.text
            self.setTitle("", for: .normal)
    
            let indicator = UIActivityIndicatorView()
            indicator.color = indicatorColor
            indicator.hidesWhenStopped = true
    
            let buttonHeight = self.bounds.size.height
            let buttonWidth = self.bounds.size.width
            indicator.center = CGPoint(x: buttonWidth/2, y: buttonHeight/2)
    
            let scale = max(min((self.frame.size.height - 4) / 21, 2.0), 0.0)
            let transform: CGAffineTransform = CGAffineTransform(scaleX: scale, y: scale)
            indicator.transform = transform
    
            self.addSubview(indicator)
            indicator.startAnimating()
        }
    
        func stopAnimating() {
            self.isEnabled = true
    
            if let titleLabel = buttonLabel {
                self.setTitle(titleLabel, for: .normal)
            }
    
            if let indicator = self.viewWithTag(tag) as? UIActivityIndicatorView {
                indicator.stopAnimating()
                indicator.removeFromSuperview()
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-31 18:12

    Swift 4:

    extension UIButton {
        func loadingIndicator(_ show: Bool) {
            let tag = 808404
            if show {
                self.isEnabled = false
                self.alpha = 0.5
                let indicator = UIActivityIndicatorView()
                let buttonHeight = self.bounds.size.height
                let buttonWidth = self.bounds.size.width
                indicator.center = CGPoint(x: buttonWidth/2, y: buttonHeight/2)
                indicator.tag = tag
                self.addSubview(indicator)
                indicator.startAnimating()
            } else {
                self.isEnabled = true
                self.alpha = 1.0
                if let indicator = self.viewWithTag(tag) as? UIActivityIndicatorView {
                    indicator.stopAnimating()
                    indicator.removeFromSuperview()
                }
            }
        }
    }
    

    Usage: button.loadingIndicator(true/false)

    0 讨论(0)
  • 2021-01-31 18:14

    i have written a library in swift, it has 7 different styles and animations to show an indicatorview in uibutton, here it is

    https://github.com/farshadjahanmanesh/loady

    0 讨论(0)
提交回复
热议问题