Wie kann ich mit Swift unter iOS 8 eine Aktivitätsanzeige mit Text anzeigen?
81
Ich möchte programmgesteuert eine Aktivitätsanzeige mit Text anzeigen, wie in der Foto-App (nach dem Bearbeiten und Speichern eines Bildes). Wie kann ich das machen?
Ich habe progressBarDisplayer so geändert, dass es eine Klasse ist, und habe es angezeigt, indem ich die Ansicht als Parameter übergeben habe. Wie würden Sie den bereits hinzugefügten progressBarDisplayer identifizieren und entfernen, wenn alles geladen ist?
Simplexität
1
@simplexity Sie können gerne eine neue Frage öffnen, Ihren aktuellen Code dort posten und mich wissen lassen, ob ich ihn mir ansehen soll.
Leo Dabus
Vielen Dank für Ihre Antwort! Am Ende habe ich die erstellte Ansicht in einer Variablen gespeichert und auf sie verwiesen removeFromSuperviewund auf gesetzt nil. Ich bin mir nicht sicher, ob es der beste Weg ist, aber Ihr oben festgelegter Code hat mir sehr geholfen!
Simplexität
etwas für Objective-C?
Artem Zaytsev
@KrishnaMeena was funktioniert es nicht? Was ist der Fehler, den Sie in welcher Zeile erhalten?
Leo Dabus
117
Während Esqs Antwort funktioniert, habe ich meine eigene Implementierung hinzugefügt, die eher der guten Komponentenarchitektur entspricht, indem ich die Ansicht in eine eigene Klasse unterteilt habe. Es wird auch die in iOS 8 eingeführte dynamische Unschärfe verwendet.
So sieht meine mit einem Bildhintergrund aus:
Der Code hierfür ist in einer eigenen UIView-Klasse gekapselt, sodass Sie ihn jederzeit wiederverwenden können.
Aktualisiert für Swift 3
Verwendung
funcviewDidLoad() {
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
}
overridefuncviewDidLoad() {
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()
}
Hallo, danke für den Code, aber weiterhin Fehler, deklarieren Sie un viewDidLoad wie vorgeschlagen und erhalten Sie den folgenden Fehler: 0x2dd698 der Klasse '_TtC22LabMaternalhaematology11ProgressHUD' implementiert nicht DoesNotRecognizeSelector: - abort (lldb). Müssen in der Lage sein, innerhalb von Verschlüssen zu zeigen und sich zu verstecken, also muss ref gemacht werden, um eine Instanz zu beanstanden ref
dancebush
@dancingbush hast du das jemals herausgefunden? Ich bekomme jetzt den gleichen Fehler aus irgendeinem Grund hat nichts geändert. Der Fehler ist gerade aufgetreten
Tyler
1
Dies ist definitiv der beste Ansatz (eine wiederverwendbare Klasse), aber der Etikettentext und der Spinner sind viel zu hell, um richtig gesehen zu werden. Und label.color = <color>wird ignoriert: -S
Pylinux
1
@ElliottMinns das habe ich gemeint (ig Pseudocode). Wenn ich es tue label.textColor = UIColor.greenColor(), hat es keinen Einfluss auf die Textfarbe.
Pylinux
2
@ElliottMinns Dies erscheint nicht in der Mitte des Bildschirms (getestet im iPhone 7 Plus Simulator)
Dee
19
Hier ist, wie dieser Code aussieht:
Hier ist mein Drag & Drop-Code:
var boxView = UIView()
overridefuncviewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
view.backgroundColor = UIColor.blackColor()
addSavingPhotoView()
//Custom button to test this appvar 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)
}
funcaddSavingPhotoView() {
// 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 initializedvar 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)
}
funcbuttonAction(sender:UIButton!) {
//When button is pressed it removes the boxView from screen
boxView.removeFromSuperview()
}
Schnelle Frage. Warum rufen Sie UIApplication.sharedApplication (). BeginIgnoringInteractionEvents () zweimal in doSomething () -> self.activityIndicatorView.startAnimating () auf und dann direkt nach diesem Aufruf?
Jason Foglia
6
Für Swift 3
Verwendung
classLoginTVC: UITableViewController{
var loadingView : LoadingView!overridefuncviewDidLoad() {
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@IBActionfuncshowLoadingView(_ sender: UIButton) {
iflet loaderView = loadingView{ // If loadingView already existsif 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@IBActionfunchideLoadingView(_ sender: UIButton) {
iflet loaderView = loadingView{ // If loadingView already exists self.loadingView.hide()
}
}
}
LoadingView-Klasse
classLoadingView{
let uiView : UIViewlet message : Stringlet 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()
}
funcsetup(){
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 dictionarylet 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 loadingViewfuncshow() {
loadingView.isHidden = false
}
// Call this method to show loadingViewfunchide(){
loadingView.isHidden = true
}
// Call this method to check if loading view already existsfuncisHidden() -> Bool{
if loadingView.isHidden == false{
returnfalse
}
else{
returntrue
}
}
}
Ihr Code ist leicht zu verstehen, aber ich arbeite nicht. Ich habe eine Schaltfläche in meiner App, um ein Bild zu speichern. Ich habe diesen Code gerade IBActionin meinen View Controller
eingefügt
Sie müssen vieweine Unteransicht der Ansicht hinzufügen, in der Sie den Spinner anzeigen möchten. Es sieht auch so aus, als würde Apples Version a verwenden UIVisualEffectView, um den Hintergrund dahinter zu verwischen.
Zev Eisenberg
Bitte beachten Sie Zevs Kommentar. Mein Code erstellt die Ansicht, aber Sie müssen sie irgendwo platzieren. Sie werden wahrscheinlich etwas Schöneres mit den Dimensionen machen wollen.
MirekE
Ok, es funktioniert hier, aber ich ändere das wait.hidesWhenStopped = false. Frage: Wie verstecke ich das Objekt view?
Thiago Arreguy
Antwort: view.removeFromSuperview ()
Thiago Arreguy
5
Für die Aktivitätsanzeige ist es besser, eine benutzerdefinierte Klasse zu erstellen.
Anstatt UIActivityIndicator in jedem UIViewController zu erstellen. Unterklasse UIView und Verwendung von jedem UIViewController.
Antworten:
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() } }
quelle
removeFromSuperview
und auf gesetztnil
. Ich bin mir nicht sicher, ob es der beste Weg ist, aber Ihr oben festgelegter Code hat mir sehr geholfen!Während Esqs Antwort funktioniert, habe ich meine eigene Implementierung hinzugefügt, die eher der guten Komponentenarchitektur entspricht, indem ich die Ansicht in eine eigene Klasse unterteilt habe. Es wird auch die in iOS 8 eingeführte dynamische Unschärfe verwendet.
So sieht meine mit einem Bildhintergrund aus:
Der Code hierfür ist in einer eigenen UIView-Klasse gekapselt, sodass Sie ihn jederzeit wiederverwenden können.
Aktualisiert für Swift 3
Verwendung
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
Ein Beispiel für die Verwendung lautet wie folgt:
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() }
Hier ist der 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 } }
Ich hoffe, dies hilft. Bitte verwenden Sie diesen Code überall dort, wo Sie ihn benötigen.
quelle
label.color = <color>
wird ignoriert: -Slabel.textColor = UIColor.greenColor()
, hat es keinen Einfluss auf die Textfarbe.Hier ist, wie dieser Code aussieht:
Hier ist mein Drag & 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() }
Hier ist eine Open Source-Version davon: https://github.com/goktugyil/CozyLoadingActivity
quelle
Basierend auf meiner vorherigen Antwort ist hier eine elegantere Lösung mit einer benutzerdefinierten Klasse:
Definieren Sie zuerst diese benutzerdefinierte Klasse:
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 }
Jetzt in deiner
UIViewController
Klasse: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() }
quelle
Für Swift 3
Verwendung
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-Klasse
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 } } }
quelle
Sie können Ihre eigenen erstellen. Zum Beispiel:
Erstellen Sie eine Ansicht mit weißem Hintergrund und abgerundeten Ecken:
var view = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 50)) view.backgroundColor = UIColor.whiteColor() view.layer.cornerRadius = 10
Fügen Sie zwei Unteransichten hinzu: a
UIActivityIndicatorView
und aUILabel
: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)
quelle
IBAction
in meinen View Controllerview
eine Unteransicht der Ansicht hinzufügen, in der Sie den Spinner anzeigen möchten. Es sieht auch so aus, als würde Apples Version a verwendenUIVisualEffectView
, um den Hintergrund dahinter zu verwischen.wait.hidesWhenStopped = false
. Frage: Wie verstecke ich das Objektview
?Für die Aktivitätsanzeige ist es besser, eine benutzerdefinierte Klasse zu erstellen.
Anstatt UIActivityIndicator in jedem UIViewController zu erstellen. Unterklasse UIView und Verwendung von jedem UIViewController.
Aktualisiert für 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() } } }
Fügen Sie diese Klasse in Ihr Projekt ein und rufen Sie dann von einem beliebigen ViewController aus als auf
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() }
quelle
Basierend auf der Antwort von "MirekE" ist hier ein Code, den ich jetzt getestet habe und der funktioniert:
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() }
quelle
einfache Aktivitätsreglerklasse !!!
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 }}
Verwendung :-
let activityIndicator = ActivityIndicator() self.view.addSubview(activityIndicator)
verstecken :-
quelle
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 } }
Verwenden:
let progress = ProgressHUD(title: "Authorization", theme: .dark) [progress].forEach(view.addSubview(_:))
quelle
Mit automatischer Breite und Themenunterstützung wird auch das Drehen bei Besetzt erkannt (Swift 3-Version)
Verwenden Sie es wie folgt:
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 } }
quelle
Dieser Code funktioniert in SWIFT 2.0.
Muss eine Variable deklarieren, um UIActivityIndicatorView zu initialisieren
let actInd: UIActivityIndicatorView = UIActivityIndicatorView()
Geben Sie diesen Code nach der Initialisierung in Ihren Controller ein.
actInd.center = ImageView.center actInd.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.WhiteLarge view.addSubview(actInd) actInd.startAnimating()
Nachdem der Downloadvorgang abgeschlossen ist, wird eine Animation ausgeblendet.
self.actInd.stopAnimating()
quelle
In Swift 3
Deklarieren Sie die Variablen, die wir verwenden werden
var activityIndicator = UIActivityIndicatorView() let loadingView = UIView() let loadingLabel = UILabel()
Legen Sie Beschriftung, Ansicht und Aktivitätsindikator fest
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) }
Animation starten
@IBAction func start_animation(_ sender: Any) { setLoadingScreen(myMsg: "Loading...") }
Animation stoppen
@IBAction func stop_animation(_ sender: Any) { self.spinner.stopAnimating() UIApplication.shared.endIgnoringInteractionEvents() self.loadingLabel.isHidden = true }
quelle
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() } } }
quelle