在UIButton中显示活动指示器

joo*_*ood 24 uibutton ios swift

我想在按下后将UIButton的内容更改为ActivityIndi​​cator.

我知道按钮有一个imageView和一个titleLabel,但我不知道如何在其中任何一个中放置一个活动指示器.

这就是我创建活动指标的方式:

let aiView = UIActivityIndicatorView(activityIndicatorStyle: .Gray)
aiView.startAnimating()
aiView.center = CGPointMake(0,0)
aiView.hidesWhenStopped = false
Run Code Online (Sandbox Code Playgroud)

Ste*_*erg 43

代码在这里找到:

https://www.snip2code.com/Snippet/777050/iOS---Swift---UIButton-subclass-for-show/

import UIKit

class LoadingButton: UIButton {
var originalButtonText: String?
var activityIndicator: UIActivityIndicatorView!

func showLoading() {
    originalButtonText = self.titleLabel?.text
    self.setTitle("", for: .normal)

    if (activityIndicator == nil) {
        activityIndicator = createActivityIndicator()
    }

    showSpinning()
}

func hideLoading() {
    self.setTitle(originalButtonText, for: .normal)
    activityIndicator.stopAnimating()
}

private func createActivityIndicator() -> UIActivityIndicatorView {
    let activityIndicator = UIActivityIndicatorView()
    activityIndicator.hidesWhenStopped = true
    activityIndicator.color = .lightGray
    return activityIndicator
}

private func showSpinning() {
    activityIndicator.translatesAutoresizingMaskIntoConstraints = false
    self.addSubview(activityIndicator)
    centerActivityIndicatorInButton()
    activityIndicator.startAnimating()
}

private func centerActivityIndicatorInButton() {
    let xCenterConstraint = NSLayoutConstraint(item: self, attribute: .centerX, relatedBy: .equal, toItem: activityIndicator, attribute: .centerX, multiplier: 1, constant: 0)
    self.addConstraint(xCenterConstraint)

    let yCenterConstraint = NSLayoutConstraint(item: self, attribute: .centerY, relatedBy: .equal, toItem: activityIndicator, attribute: .centerY, multiplier: 1, constant: 0)
    self.addConstraint(yCenterConstraint)
}
}
Run Code Online (Sandbox Code Playgroud)

  • 从 iOS 15 开始,您可以使用 `button.configuration?.showsActivityIndi​​cator = true` (3认同)
  • 请记住将故事板中按钮的类更新为自定义类。例如,身份检查器 > 自定义类 = LoadingButton。否则你会得到`EXC_BAD_ACCESS` (2认同)

Kur*_*t J 21

@Boris:这不应该在扩展名中.

这里是快速的3/4,改进的代码:禁用按钮,使用图像和标题.

class LoadingButton: UIButton {

    struct ButtonState {
        var state: UIControlState
        var title: String?
        var image: UIImage?
    }

    private (set) var buttonStates: [ButtonState] = []
    private lazy var activityIndicator: UIActivityIndicatorView = {
        let activityIndicator = UIActivityIndicatorView()
        activityIndicator.hidesWhenStopped = true
        activityIndicator.color = self.titleColor(for: .normal)
        self.addSubview(activityIndicator)
        activityIndicator.translatesAutoresizingMaskIntoConstraints = false
        let xCenterConstraint = NSLayoutConstraint(item: self, attribute: .centerX, relatedBy: .equal, toItem: activityIndicator, attribute: .centerX, multiplier: 1, constant: 0)
        let yCenterConstraint = NSLayoutConstraint(item: self, attribute: .centerY, relatedBy: .equal, toItem: activityIndicator, attribute: .centerY, multiplier: 1, constant: 0)
        self.addConstraints([xCenterConstraint, yCenterConstraint])
        return activityIndicator
    }()

    func showLoading() {
        activityIndicator.startAnimating()
        var buttonStates: [ButtonState] = []
        for state in [UIControlState.disabled] {
            let buttonState = ButtonState(state: state, title: title(for: state), image: image(for: state))
            buttonStates.append(buttonState)
            setTitle("", for: state)
            setImage(UIImage(), for: state)
        }
        self.buttonStates = buttonStates
        isEnabled = false
    }

    func hideLoading() {
        activityIndicator.stopAnimating()
        for buttonState in buttonStates {
            setTitle(buttonState.title, for: buttonState.state)
            setImage(buttonState.image, for: buttonState.state)
        }
        isEnabled = true
    }

}
Run Code Online (Sandbox Code Playgroud)


小智 12

Swift 4.0稍作修改

class LoadingUIButton: UIButton {

    @IBInspectable var indicatorColor : UIColor = .lightGray

    var originalButtonText: String?
    var activityIndicator: UIActivityIndicatorView!

    func showLoading() {
        originalButtonText = self.titleLabel?.text
        self.setTitle("", for: .normal)

        if (activityIndicator == nil) {
            activityIndicator = createActivityIndicator()
        }

        showSpinning()
    }

    func hideLoading() {
        DispatchQueue.main.async(execute: {
            self.setTitle(self.originalButtonText, for: .normal)
            self.activityIndicator.stopAnimating()
        })
    }

    private func createActivityIndicator() -> UIActivityIndicatorView {
        let activityIndicator = UIActivityIndicatorView()
        activityIndicator.hidesWhenStopped = true
        activityIndicator.color = indicatorColor
        return activityIndicator
    }

    private func showSpinning() {
        activityIndicator.translatesAutoresizingMaskIntoConstraints = false
        self.addSubview(activityIndicator)
        centerActivityIndicatorInButton()
        activityIndicator.startAnimating()
    }

    private func centerActivityIndicatorInButton() {
        let xCenterConstraint = NSLayoutConstraint(item: self, attribute: .centerX, relatedBy: .equal, toItem: activityIndicator, attribute: .centerX, multiplier: 1, constant: 0)
        self.addConstraint(xCenterConstraint)

        let yCenterConstraint = NSLayoutConstraint(item: self, attribute: .centerY, relatedBy: .equal, toItem: activityIndicator, attribute: .centerY, multiplier: 1, constant: 0)
        self.addConstraint(yCenterConstraint)
    }

}
Run Code Online (Sandbox Code Playgroud)


Kri*_*ian 10

斯威夫特 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()
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法button.loadingIndicator(true/false)


Far*_*esh 6

我已经迅速编写了一个库,它具有7种不同的样式和动画,以在uibutton中显示一个indicatorview,这里是

https://github.com/farshadjahanmanesh/loady

在此处输入图片说明


Kel*_*Fok 5

斯威夫特 5,Xcode 11.3

我已经为我的用例修改了它以包含按钮文本和微调器

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)
}

}
Run Code Online (Sandbox Code Playgroud)

如果您使用的是故事板,请确保您的按钮类型为 LoadingButton(在您的故事板和视图控制器文件上执行此操作,否则会崩溃)

@IBOutlet weak var myButton: LoadingButton!
Run Code Online (Sandbox Code Playgroud)

并使用它,

myButton.loadIndicator(true)
Run Code Online (Sandbox Code Playgroud)

截屏