如何在 iOS8上用 Swift 显示带文本的活动指示器?

我想显示,以编程方式,一个活动指示器与文本,就像在照片应用程序(后编辑和保存图片)。我怎么能这么做?

enter image description here

124736 次浏览

你可以创造你自己的,例如:

创建一个白色背景和圆角的视图:

var view = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 50))
view.backgroundColor = UIColor.whiteColor()
view.layer.cornerRadius = 10

添加两个子视图,一个 UIActivityIndicatorView和一个 UILabel:

var wait = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
wait.color = UIColor.blackColor()
wait.hidesWhenStopped = false




var text = UILabel(frame: CGRect(x: 60, y: 0, width: 200, height: 50))
text.text = "Processing..."


view.addSubview(wait)
view.addSubview(text)

下面是这段代码的样子:

enter image description here

下面是我的拖放代码:

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

下面是这个程序的开源版本: https://github.com/goktugyil/CozyLoadingActivity

Xcode 9.0• Swift 4.0


import UIKit
class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var filterButton: UIButton!
@IBOutlet weak var saveButton: UIButton!
let destinationUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
.appendingPathComponent("filteredImage.png")
let imagePicker = UIImagePickerController()
let messageFrame = UIView()
var activityIndicator = UIActivityIndicatorView()
var strLabel = UILabel()
let effectView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
func activityIndicator(_ title: String) {
strLabel.removeFromSuperview()
activityIndicator.removeFromSuperview()
effectView.removeFromSuperview()
strLabel = UILabel(frame: CGRect(x: 50, y: 0, width: 160, height: 46))
strLabel.text = title
strLabel.font = .systemFont(ofSize: 14, weight: .medium)
strLabel.textColor = UIColor(white: 0.9, alpha: 0.7)
effectView.frame = CGRect(x: view.frame.midX - strLabel.frame.width/2, y: view.frame.midY - strLabel.frame.height/2 , width: 160, height: 46)
effectView.layer.cornerRadius = 15
effectView.layer.masksToBounds = true
activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .white)
activityIndicator.frame = CGRect(x: 0, y: 0, width: 46, height: 46)
activityIndicator.startAnimating()
effectView.contentView.addSubview(activityIndicator)
effectView.contentView.addSubview(strLabel)
view.addSubview(effectView)
}
func saveImage() {
do {
try imageView.image?.data?.write(to: destinationUrl, options: .atomic)
print("file saved")
} catch {
print(error)
}
}
func applyFilterToImage() {
imageView.image = imageView.image?.applying(contrast: 1.5)
}
override func viewDidLoad() {
super.viewDidLoad()
guard let url = URL(string: "https://upload.wikimedia.org/wikipedia/commons/a/a8/VST_images_the_Lagoon_Nebula.jpg"), let data = try? Data(contentsOf: url), let image = UIImage(data: data) else { return }
view.backgroundColor = UIColor(white: 0, alpha: 1)
imageView.image = image
}
@IBAction func startSavingImage(_ sender: AnyObject) {
saveButton.isEnabled = false
filterButton.isEnabled = false
activityIndicator("Saving Image")
DispatchQueue.main.async {
self.saveImage()
DispatchQueue.main.async {
self.effectView.removeFromSuperview()
self.saveButton.isEnabled = true
self.filterButton.isEnabled = true
}
}
}
@IBAction func filterAction(_ sender: AnyObject) {
filterButton.isEnabled = false
saveButton.isEnabled = false
activityIndicator("Applying Filter")
DispatchQueue.main.async {
self.applyFilterToImage()
DispatchQueue.main.async {
self.effectView.removeFromSuperview()
self.filterButton.isEnabled = true
self.saveButton.isEnabled = true
}
}
}
@IBAction func cameraAction(_ sender: AnyObject) {
if UIImagePickerController.isSourceTypeAvailable(.camera) {
imagePicker.delegate = self
imagePicker.sourceType = .camera
present(imagePicker, animated: true)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [AnyHashable: Any]!) {
dismiss(animated: true, completion: nil)
imageView.image = image
}
}

extension Data {
var image: UIImage? { return UIImage(data: self) }
}

extension UIImage {
var data: Data? { return UIImagePNGRepresentation(self) }
func applying(contrast value: NSNumber) -> UIImage? {
guard let ciImage = CIImage(image: self)?.applyingFilter("CIColorControls", withInputParameters: [kCIInputContrastKey: value]) else { return nil }
UIGraphicsBeginImageContextWithOptions(size, false, scale)
defer { UIGraphicsEndImageContext() }
UIImage(ciImage: ciImage).draw(in: CGRect(origin: .zero, size: size))
return UIGraphicsGetImageFromCurrentImageContext()
}
}

虽然 Esq 的回答是有效的,但我已经添加了我自己的实现,通过将视图分离到它自己的类中,这更符合优秀的组件架构。它还使用了 iOS8中引入的动态模糊技术。

下面是我的背景图片的样子:

enter image description here

这些代码封装在它自己的 UIView 类中,这意味着您可以随时重用它。

更新为 Swift 3

用法

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 代码

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

如何使用它的一个例子是这样的:

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

以下是 UIView 代码:

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

我希望这有所帮助,请随时使用这个代码,无论您需要什么。

基于“ MirekE”的回答,这里有一个代码,我现在测试和它的工作:

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

基于我之前的回答,这里有一个更优雅的自定义类解决方案:

首先定义这个自定义类:

import UIKit
import Foundation


class ActivityIndicatorView
{
var view: UIView!


var activityIndicator: UIActivityIndicatorView!


var title: String!


init(title: String, center: CGPoint, width: CGFloat = 200.0, height: CGFloat = 50.0)
{
self.title = title


let x = center.x - width/2.0
let y = center.y - height/2.0


self.view = UIView(frame: CGRect(x: x, y: y, width: width, height: height))
self.view.backgroundColor = UIColor(red: 255.0/255.0, green: 204.0/255.0, blue: 51.0/255.0, alpha: 0.5)
self.view.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 = title
titleLabel.textColor = UIColor.blackColor()


self.view.addSubview(self.activityIndicator)
self.view.addSubview(titleLabel)
}


func getViewActivityIndicator() -> UIView
{
return self.view
}


func startAnimating()
{
self.activityIndicator.startAnimating()
UIApplication.sharedApplication().beginIgnoringInteractionEvents()
}


func stopAnimating()
{
self.activityIndicator.stopAnimating()
UIApplication.sharedApplication().endIgnoringInteractionEvents()


self.view.removeFromSuperview()
}
//end
}

现在上 UIViewController课:

var activityIndicatorView: ActivityIndicatorView!


override func viewDidLoad()
{
super.viewDidLoad()


self.activityIndicatorView = ActivityIndicatorView(title: "Processing...", center: self.view.center)
self.view.addSubview(self.activityIndicatorView.getViewActivityIndicator())


}


func doSomething()
{
self.activityIndicatorView.startAnimating()
UIApplication.sharedApplication().beginIgnoringInteractionEvents()


//do something here that will taking time


self.activityIndicatorView.stopAnimating()
}

对于活动指示器,最好创建一个自定义类。

而不是在每个 UIViewController 中创建 UIActivityIndicator。子类 UIView 并从任何 UIViewController 中使用。

更新为 Swift 5.0:

import UIKit
import Foundation
class ProgressIndicator: UIView {


var indicatorColor:UIColor
var loadingViewColor:UIColor
var loadingMessage:String
var messageFrame = UIView()
var activityIndicator = UIActivityIndicatorView()


init(inview:UIView,loadingViewColor:UIColor,indicatorColor:UIColor,msg:String){


self.indicatorColor = indicatorColor
self.loadingViewColor = loadingViewColor
self.loadingMessage = msg
super.init(frame: CGRect(x: inview.frame.midX - 90, y: inview.frame.midY - 250 , width: 180, height: 50))
initalizeCustomIndicator()


}
convenience init(inview:UIView) {


self.init(inview: inview,loadingViewColor: UIColor.brown,indicatorColor:UIColor.black, msg: "Loading..")
}
convenience init(inview:UIView,messsage:String) {


self.init(inview: inview,loadingViewColor: UIColor.brown,indicatorColor:UIColor.black, msg: messsage)
}


required init?(coder aDecoder: NSCoder) {


fatalError("init(coder:) has not been implemented")
}


func initalizeCustomIndicator(){


messageFrame.frame = self.bounds
activityIndicator = UIActivityIndicatorView(style: UIActivityIndicatorView.Style.medium)
activityIndicator.tintColor = indicatorColor
activityIndicator.hidesWhenStopped = true
activityIndicator.frame = CGRect(x: self.bounds.origin.x + 6, y: 0, width: 20, height: 50)
print(activityIndicator.frame)
let strLabel = UILabel(frame:CGRect(x: self.bounds.origin.x + 30, y: 0, width: self.bounds.width - (self.bounds.origin.x + 30) , height: 50))
strLabel.text = loadingMessage
strLabel.adjustsFontSizeToFitWidth = true
strLabel.textColor = UIColor.white
messageFrame.layer.cornerRadius = 15
messageFrame.backgroundColor = loadingViewColor
messageFrame.alpha = 0.8
messageFrame.addSubview(activityIndicator)
messageFrame.addSubview(strLabel)




}


func  start(){
//check if view is already there or not..if again started
if !self.subviews.contains(messageFrame){


activityIndicator.startAnimating()
self.addSubview(messageFrame)


}
}


func stop(){


if self.subviews.contains(messageFrame){


activityIndicator.stopAnimating()
messageFrame.removeFromSuperview()


}
}
}

将此类放入项目中,然后从任何 ViewController 调用

var indicator:ProgressIndicator?
override func viewDidLoad() {
super.viewDidLoad()


//indicator = ProgressIndicator(inview: self.view,messsage: "Hello from Nepal..")
//self.view.addSubview(indicator!)
//OR
indicator = ProgressIndicator(inview:self.view,loadingViewColor: UIColor.grayColor(), indicatorColor: UIColor.blackColor(), msg: "Landing within minutes,Please hold tight..")
self.view.addSubview(indicator!)


}


@IBAction func startBtn(sender: AnyObject) {
indicator!.start()
}




@IBAction func stopBtn(sender: AnyObject) {
indicator!.stop()
}

此代码在 SWIFT 2.0中可以工作。

必须为初始化 UIActivityIndicatorView 声明一个变量

let actInd: UIActivityIndicatorView = UIActivityIndicatorView()

初始化后,将此代码放入控制器中。

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

在你的下载过程完成后,然后隐藏一个动画。

self.actInd.stopAnimating()

具有自动宽度和主题支持,也检测旋转忙(迅捷3版本)

使用方法如下:

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

简单的活动控制器类! ! !

class ActivityIndicator: UIVisualEffectView {




let activityIndictor: UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.WhiteLarge)
let label: UILabel = UILabel()
let blurEffect = UIBlurEffect(style: .Dark)
let vibrancyView: UIVisualEffectView


init() {


self.vibrancyView = UIVisualEffectView(effect: UIVibrancyEffect(forBlurEffect: blurEffect))
super.init(effect: blurEffect)
self.setup()
}


required init?(coder aDecoder: NSCoder) {


self.vibrancyView = UIVisualEffectView(effect: UIVibrancyEffect(forBlurEffect: blurEffect))
super.init(coder: aDecoder)
self.setup()
}


func setup() {


contentView.addSubview(vibrancyView)
vibrancyView.contentView.addSubview(activityIndictor)
activityIndictor.startAnimating()
}


override func didMoveToSuperview() {
super.didMoveToSuperview()


if let superview = self.superview {
let width: CGFloat = 75.0
let height: CGFloat = 75.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(18, height / 2 - activityIndicatorSize / 2,
activityIndicatorSize,
activityIndicatorSize)
layer.cornerRadius = 8.0
layer.masksToBounds = true


}
}


func show() {
self.hidden = false
}


func hide() {
self.hidden = true
}}

用途:-

let activityIndicator = ActivityIndicator()
self.view.addSubview(activityIndicator)

隐藏:-

activityIndicator.hide()

在 Swift 3

声明我们将使用的变量

var activityIndicator = UIActivityIndicatorView()
let loadingView = UIView()
let loadingLabel = UILabel()

设置标签、视图和 activityIndicator

func setLoadingScreen(myMsg : String) {
let width: CGFloat = 120
let height: CGFloat = 30
let x = (self.view.frame.width / 2) - (width / 2)
let y = (169 / 2) - (height / 2) + 60
loadingView.frame = CGRect(x: x, y: y, width: width, height: height)
self.loadingLabel.textColor = UIColor.white
self.loadingLabel.textAlignment = NSTextAlignment.center
self.loadingLabel.text = myMsg
self.loadingLabel.frame = CGRect(x: 0, y: 0, width: 160, height: 30)
self.loadingLabel.isHidden = false
self.activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.white
self.activityIndicator.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
self.activityIndicator.startAnimating()
loadingView.addSubview(self.spinner)
loadingView.addSubview(self.loadingLabel)
self.view.addSubview(loadingView)
}

开始动画制作

@IBAction func start_animation(_ sender: Any) {
setLoadingScreen(myMsg: "Loading...")
}

停止动画

@IBAction func stop_animation(_ sender: Any) {
self.spinner.stopAnimating()
UIApplication.shared.endIgnoringInteractionEvents()
self.loadingLabel.isHidden = true
}

为了 Swift 3

enter image description here

用法

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

加载视图类

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

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

用途:

let progress = ProgressHUD(title: "Authorization", theme: .dark)
[progress].forEach(view.addSubview(_:))
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()
}
}
}

为了 Swift 5

WKWebview 中带标签的指示器

var strLabel = UILabel()
let effectView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
let loadingTextLabel = UILabel()
   

@IBOutlet var indicator: UIActivityIndicatorView!
@IBOutlet var webView: WKWebView!
    

var refController:UIRefreshControl = UIRefreshControl()
    

    

override func viewDidLoad() {
webView = WKWebView(frame: CGRect.zero)
webView.navigationDelegate = self
webView.uiDelegate = self as? WKUIDelegate
        

let preferences = WKPreferences()
preferences.javaScriptEnabled = true
let configuration = WKWebViewConfiguration()
configuration.preferences = preferences
       

        

webView.allowsBackForwardNavigationGestures = true
        

webView.load(URLRequest(url: URL(string: "https://www.google.com")!))
setBackground()
        

}
    



    

func setBackground() {
view.addSubview(webView)
webView.translatesAutoresizingMaskIntoConstraints = false
webView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
webView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
webView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
webView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
}
    

func showActivityIndicator(show: Bool) {
if show {
            

            

strLabel = UILabel(frame: CGRect(x: 55, y: 0, width: 400, height: 66))
strLabel.text = "Please Wait. Checking Internet Connection..."
strLabel.font = UIFont(name: "Avenir Light", size: 12)
            

           

strLabel.textColor = UIColor(white: 0.9, alpha: 0.7)
           

effectView.frame = CGRect(x: view.frame.midX - strLabel.frame.width/2, y: view.frame.midY - strLabel.frame.height/2 , width: 300, height: 66)
effectView.layer.cornerRadius = 15
effectView.layer.masksToBounds = true
indicator = UIActivityIndicatorView(style: .white)
indicator.frame = CGRect(x: 0, y: 0, width: 66, height: 66)
indicator.startAnimating()
effectView.contentView.addSubview(indicator)
effectView.contentView.addSubview(strLabel)
indicator.transform = CGAffineTransform(scaleX: 1.4, y: 1.4);
effectView.center = webView.center
view.addSubview(effectView)
            

            

} else {
strLabel.removeFromSuperview()
effectView.removeFromSuperview()
indicator.removeFromSuperview()
indicator.stopAnimating()
}
}

Here is my screenshort