Làm cách nào để hiển thị chỉ báo hoạt động bằng văn bản trên iOS 8 với Swift?


81

Tôi muốn hiển thị, theo chương trình, chỉ báo hoạt động bằng văn bản, giống như chỉ báo trong ứng dụng Ảnh (sau khi chỉnh sửa và lưu ảnh). Tôi có thể làm cái này như thế nào?

nhập mô tả hình ảnh ở đây


2
Dưới đây là một phiên bản mã nguồn mở của tôi này làm github.com/goktugyil/CozyLoadingActivity
Esqarrouth

Câu trả lời:


130

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


Tôi đã sửa đổi processBarDisplayer thành một lớp và hiển thị nó bằng cách chuyển vào dạng xem dưới dạng tham số. Làm cách nào để bạn xác định được processBarDisplayer đã được thêm và xóa nó khi mọi thứ tải xong?
simplexity

1
@simplexity vui lòng mở một câu hỏi mới, đăng mã thực của bạn lên đó và cho tôi biết nếu bạn muốn tôi xem qua.
Leo Dabus

Cám ơn phản hồi của bạn! Tôi thực sự đã kết thúc việc lưu trữ dạng xem đã tạo trong một biến và tham chiếu nó đến removeFromSuperviewvà đặt thành nil. Không chắc đó có phải là cách tốt nhất hay không nhưng bộ mã của bạn ở trên đã giúp ích rất nhiều!
simplexity

bất cứ điều gì cho Objective-C?
Artem Zaytsev

@KrishnaMeena những gì nó không hoạt động? Lỗi bạn đang nhận được ở dòng nào?
Leo Dabus,

117

Trong khi câu trả lời của Esq hoạt động, tôi đã thêm triển khai của riêng mình phù hợp hơn với kiến ​​trúc thành phần tốt bằng cách tách chế độ xem thành lớp riêng của nó. Nó cũng sử dụng tính năng làm mờ động được giới thiệu trong iOS 8.

Đây là giao diện của tôi với nền hình ảnh:

nhập mô tả hình ảnh ở đây

Mã cho điều này được gói gọn trong lớp UIView của riêng nó, có nghĩa là bạn có thể sử dụng lại nó bất cứ khi nào bạn muốn.

Đã cập nhật cho Swift 3

Sử dụng

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
}

Mã 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

Một ví dụ về cách sử dụng nó như sau:

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

Đây là mã 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
    }
}

Tôi hy vọng điều này sẽ hữu ích, vui lòng sử dụng mã này bất cứ nơi nào bạn cần.


Xin chào, Cảm ơn vì mã nhưng tiếp tục gặp lỗi, khai báo un viewDidLoad như được đề xuất và nhận được lỗi sau: 0x2dd698 của lớp '_TtC22LabMaternalhaematology11ProgressHUD' không thực hiện doesNotRecognizeSelector: - abort (lldb). Cần phải có khả năng hiển thị và ẩn bên trong đóng cửa nên cần phải thực hiện ref để phản đối một ref dụ
dancingbush

@dancingbush bạn đã bao giờ tìm ra điều này chưa? Tôi gặp phải lỗi tương tự bây giờ vì một số lý do đã không thay đổi bất cứ điều gì lỗi chỉ bắt đầu xảy ra
Tyler

1
Đây chắc chắn là cách tiếp cận tốt nhất (một lớp có thể tái sử dụng), nhưng văn bản nhãn và con quay quá nhạt để có thể nhìn thấy đúng cách. Và label.color = <color>bị bỏ qua: -S
Pylinux.

1
@ElliottMinns đó là ý của tôi (tức là mã giả). Nếu tôi làm vậy, label.textColor = UIColor.greenColor()nó không ảnh hưởng đến màu văn bản.
Pylinux

2
@ElliottMinns Điều này không xuất hiện ở giữa màn hình (Đã kiểm tra nó trong trình mô phỏng iPhone 7 Plus)
Dee

19

Đây là cách mã này trông như thế nào:

nhập mô tả hình ảnh ở đây

Đây là mã kéo và thả của tôi:

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

Đây là phiên bản mã nguồn mở của cái này: https://github.com/goktugyil/CozyLoadingActivity


2
Dưới đây là một phiên bản mã nguồn mở của tôi này làm github.com/goktugyil/CozyLoadingActivity
Esqarrouth

10

Dựa trên câu trả lời trước đây của tôi, đây là một giải pháp thanh lịch hơn với lớp tùy chỉnh:

Đầu tiên xác định lớp tùy chỉnh này:

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
}

Bây giờ trên UIViewControllerlớp của bạn :

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

Câu hỏi nhanh. Tại sao bạn lại gọi UIApplication.sharedApplication (). BeginIgnoringInteractionEvents () hai lần trong doSomething () -> self.activityIndicatorView.startAnimating () rồi ngay sau lệnh gọi đó?
Jason Foglia

6

Đối với Swift 3

nhập mô tả hình ảnh ở đây

Sử dụng

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

Lớp LoadingView

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

5

Bạn có thể tạo của riêng bạn. Ví dụ:

Tạo chế độ xem với nền trắng và các góc tròn:

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

Thêm hai lượt xem phụ, a UIActivityIndicatorViewvà a 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)

mã của bạn rất dễ hiểu nhưng tôi không làm việc. Tôi có một nút trong ứng dụng của mình để lưu hình ảnh. Tôi chỉ dán đoạn mã này để nó IBActiontrong điều khiển điểm của tôi và không có gì xảy ra
rodrigoalvesvieira

Bạn cần thêm viewlàm chế độ xem phụ của chế độ xem mà bạn đang cố gắng hiển thị vòng quay. Ngoài ra, có vẻ như phiên bản của Apple có thể đang sử dụng tính UIVisualEffectViewnăng làm mờ nền đằng sau nó.
Zev Eisenberg

Hãy xem bình luận của Zev. Mã của tôi tạo chế độ xem, nhưng bạn cần đặt nó ở đâu đó. Bạn có thể sẽ muốn làm điều gì đó đẹp hơn với các kích thước.
MirekE

Ok, nó hoạt động ở đây, nhưng tôi thay đổi điều này wait.hidesWhenStopped = false. Câu hỏi: làm thế nào để ẩn đối tượng view?
Thiago Arreguy

Trả lời: view.removeFromSuperview ()
Thiago Arreguy.

5

Đối với chỉ báo hoạt động, tốt hơn hết bạn nên tạo một lớp tùy chỉnh.

Thay vì tạo UIActivityIndicator trong mỗi UIViewController.Subclass UIView và sử dụng từ bất kỳ UIViewController nào.

Cập nhật cho 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()

    }
}
}

Đặt lớp này vào dự án của bạn và sau đó gọi từ bất kỳ ViewController nào bằng

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

4

Dựa trên câu trả lời "MirekE", đây là mã mà tôi đã kiểm tra ngay bây giờ và nó đang hoạt động:

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

2

lớp điều khiển hoạt động đơn giản !!!

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

sử dụng :-

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

trốn :-

activityIndicator.hide()

2

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

Sử dụng:

let progress = ProgressHUD(title: "Authorization", theme: .dark)
[progress].forEach(view.addSubview(_:))

2

Với độ rộng tự động và hỗ trợ chủ đề cũng phát hiện xoay khi đang bận (phiên bản Swift 3)

Sử dụng nó như dưới đây:

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

1

Mã này hoạt động trong SWIFT 2.0.

Phải khai báo một biến để khởi tạo UIActivityIndicatorView

let actInd: UIActivityIndicatorView = UIActivityIndicatorView() 

Sau khi khởi tạo, hãy đặt mã này vào bộ điều khiển của bạn.

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

sau khi quá trình tải xuống của bạn hoàn tất, hãy ẩn một hoạt ảnh.

self.actInd.stopAnimating()

1

Trong Swift 3

Khai báo các biến mà chúng ta sẽ sử dụng

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

Đặt nhãn, chế độ xem và hoạt độngIndicator

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

Bắt đầu hoạt ảnh

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

Ngừng hoạt ảnh

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

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

ViewControllerUtils sử dụng cho tất cả các bộ điều khiển xem, nơi như với WebView vui lòng sử dụng ViewControllerUtils2 ..
iAj
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.