Ios 在多个视图控制器中使用相同的UIActivityIndicatorView

Ios 在多个视图控制器中使用相同的UIActivityIndicatorView,ios,objective-c,xcode,Ios,Objective C,Xcode,我有一个带有各种视图控制器的简单iOS应用程序。 每个视图控制器都有不同的功能,但每个视图控制器都有“加载”按钮,当被触发时,它会向委托方法发送请求并获得结果 我想使用UIActivityIndicatorView,它将在用户单击按钮时启动,并在委托方法上停止。 显然,我希望每个VC上的指示器看起来都一样,因此我对其进行了属性设置,并且在每个viewDidLoad方法上使用以下代码: self.indicator = [[UIActivityIndicatorView alloc] initWi

我有一个带有各种视图控制器的简单iOS应用程序。 每个视图控制器都有不同的功能,但每个视图控制器都有“加载”按钮,当被触发时,它会向委托方法发送请求并获得结果

我想使用UIActivityIndicatorView,它将在用户单击按钮时启动,并在委托方法上停止。 显然,我希望每个VC上的指示器看起来都一样,因此我对其进行了属性设置,并且在每个viewDidLoad方法上使用以下代码:

self.indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; 
self.indicator.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.6f];
self.indicator.frame = CGRectMake(40.0, 20.0, 100.0, 100.0);
self.indicator.center = self.view.center;
问题是,我在同一个对象上使用相同的参数,在每个视图控制器上复制和粘贴这些线。 假设我想在下一个版本中更改样式,我需要更改10次


使用某种静态指示器的最佳方式是什么?该指示器将使用这些参数进行设置,并根据需要进行开关设置

您可以在
ui窗口中创建活动指示器,然后可以在任何
ui视图控制器中显示/隐藏它

要获取窗口,请使用:
UIApplication.shared.keyWindow

您可以创建单个视图控制器以在所有视图控制器中显示加载指示器。您需要编写一次代码,将以下代码放入AppDelegate文件中

注意:我没有在Objective-C中工作,下面是Swift中的代码。因此,您需要转换目标C中的代码

首先在ProgressVC中添加以下代码:

ProgressVC.swift:

class func viewController() -> ProgressVC {
   return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ProgressVC") as! ProgressVC
}
var progressVC : ProgressVC?
static let shared = UIApplication.shared.delegate as! AppDelegate

func showLoading(isShow: Bool) {

    if isShow {

        // Remove progress view if already exist
        if progressVC != nil {
            progressVC?.view.removeFromSuperview()
            progressVC = nil
        }

        progressVC = ProgressVC.viewController()
        AppDelegate.shared.window?.addSubview((progressVC?.view)!)

    } else {

        if progressVC != nil {
            progressVC?.view.removeFromSuperview()
        }
    }
}
AppDelegate.shared.showLoading(isShow: true)
AppDelegate.shared.showLoading(isShow: false)
在AppDelegate中添加以下代码

AppDelegate.swift:

class func viewController() -> ProgressVC {
   return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ProgressVC") as! ProgressVC
}
var progressVC : ProgressVC?
static let shared = UIApplication.shared.delegate as! AppDelegate

func showLoading(isShow: Bool) {

    if isShow {

        // Remove progress view if already exist
        if progressVC != nil {
            progressVC?.view.removeFromSuperview()
            progressVC = nil
        }

        progressVC = ProgressVC.viewController()
        AppDelegate.shared.window?.addSubview((progressVC?.view)!)

    } else {

        if progressVC != nil {
            progressVC?.view.removeFromSuperview()
        }
    }
}
AppDelegate.shared.showLoading(isShow: true)
AppDelegate.shared.showLoading(isShow: false)
现在,您需要使用AppDelegate的共享实例调用上面的方法。从情节提要中启用UIActivityIndicatorView的动画属性

显示:

class func viewController() -> ProgressVC {
   return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ProgressVC") as! ProgressVC
}
var progressVC : ProgressVC?
static let shared = UIApplication.shared.delegate as! AppDelegate

func showLoading(isShow: Bool) {

    if isShow {

        // Remove progress view if already exist
        if progressVC != nil {
            progressVC?.view.removeFromSuperview()
            progressVC = nil
        }

        progressVC = ProgressVC.viewController()
        AppDelegate.shared.window?.addSubview((progressVC?.view)!)

    } else {

        if progressVC != nil {
            progressVC?.view.removeFromSuperview()
        }
    }
}
AppDelegate.shared.showLoading(isShow: true)
AppDelegate.shared.showLoading(isShow: false)
隐藏:

class func viewController() -> ProgressVC {
   return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ProgressVC") as! ProgressVC
}
var progressVC : ProgressVC?
static let shared = UIApplication.shared.delegate as! AppDelegate

func showLoading(isShow: Bool) {

    if isShow {

        // Remove progress view if already exist
        if progressVC != nil {
            progressVC?.view.removeFromSuperview()
            progressVC = nil
        }

        progressVC = ProgressVC.viewController()
        AppDelegate.shared.window?.addSubview((progressVC?.view)!)

    } else {

        if progressVC != nil {
            progressVC?.view.removeFromSuperview()
        }
    }
}
AppDelegate.shared.showLoading(isShow: true)
AppDelegate.shared.showLoading(isShow: false)
屏幕截图:

class func viewController() -> ProgressVC {
   return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ProgressVC") as! ProgressVC
}
var progressVC : ProgressVC?
static let shared = UIApplication.shared.delegate as! AppDelegate

func showLoading(isShow: Bool) {

    if isShow {

        // Remove progress view if already exist
        if progressVC != nil {
            progressVC?.view.removeFromSuperview()
            progressVC = nil
        }

        progressVC = ProgressVC.viewController()
        AppDelegate.shared.window?.addSubview((progressVC?.view)!)

    } else {

        if progressVC != nil {
            progressVC?.view.removeFromSuperview()
        }
    }
}
AppDelegate.shared.showLoading(isShow: true)
AppDelegate.shared.showLoading(isShow: false)

这是我在swift 4.1中使用的一个

import UIKit

class ProgressView {

    // MARK: - Variables
    private var containerView = UIView()
    private var progressView = UIView()
    private var activityIndicator = UIActivityIndicatorView()

    static var shared = ProgressView()

    // To close for instantiation
    private init() {}

    // MARK: - Functions
     func startAnimating(view: UIView = (UIApplication.shared.keyWindow?.rootViewController?.view)!) {
        containerView.center = view.center
        containerView.frame = view.frame
        containerView.backgroundColor = UIColor(hex: 0xffffff, alpha: 0.5)

        progressView.frame = CGRect(x: 0, y: 0, width: 80, height: 80)
        progressView.center = containerView.center
        progressView.backgroundColor = UIColor(hex: 0x444444, alpha: 0.7)
        progressView.clipsToBounds = true
        progressView.cornerRadius = 10

        activityIndicator.frame = CGRect(x: 0, y: 0, width: 60, height: 60)
        activityIndicator.center = CGPoint(x: progressView.bounds.width/2, y: progressView.bounds.height/2)

        activityIndicator.style = .whiteLarge

        view.addSubview(containerView)
        containerView.addSubview(progressView)
        progressView.addSubview(activityIndicator)

        activityIndicator.startAnimating()
    }

    /// animate UIActivityIndicationView without blocking UI
    func startSmoothAnimation(view: UIView = (UIApplication.shared.keyWindow?.rootViewController?.view)!) {
        activityIndicator.frame = CGRect(x: 0, y: 0, width: 60, height: 60)
        activityIndicator.center = view.center
        activityIndicator.style = .whiteLarge
        activityIndicator.color = UIColor.gray
        view.addSubview(activityIndicator)
        activityIndicator.startAnimating()
    }

    func stopAnimatimating() {
        activityIndicator.stopAnimating()
        containerView.removeFromSuperview()
    }

}

extension UIColor {
    convenience init(hex: UInt32, alpha: CGFloat) {
        let red = CGFloat((hex & 0xFF0000) >> 16)/256.0
        let green = CGFloat((hex & 0xFF00) >> 8)/256.0
        let blue = CGFloat(hex & 0xFF)/256.0
        self.init(red: red, green: green, blue: blue, alpha: alpha)
    }
}

// usage 
 ProgressView.shared.startAnimating()
// to stop 
 ProgressView.shared.stopAnimatimating()
Hope it helps

我建议您为视图控制器创建一个超类,并在其中添加微调器功能,并让视图控制器从中继承

超类视图控制器的外观如下所示:

// .h-file
@interface SuperclassViewController : UIViewController

- (void)showIndicator;
- (void)hideIndicator;

@end


现在,要继承它,请在视图控制器.h文件中执行以下操作:

#import "SuperclassViewController.h"

@interface YourViewController : SuperclassViewController;

/** properties and methods */

@end

然后,您可以随时在视图控制器中调用
[self showIndicator]
[self hideIndicator]
,而无需任何额外编码

谢谢大家的帮助, 我决定创建一个具有UIActivityIndicatorView变量的单例类

这是该类的声明:

#import "ProgressView.h"

@interface ProgressView()

@property (nonatomic) UIActivityIndicatorView *indicator;
+(ProgressView *)shared;
@end

@implementation ProgressView

+ (ProgressView *)shared {
    static ProgressView* sharedVC = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedVC = [[self alloc] init];
    });
    return sharedVC;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        self.indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
        self.indicator.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.6f];
        self.indicator.frame = CGRectMake(40.0, 20.0, 100.0, 100.0);
    }
    return self;
}

- (void)startAnimation:(UIView *)view {
    self.indicator.center = view.center;
    self.indicator.hidden = NO;
    [self.indicator startAnimating];
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 12 * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        if ([self.indicator isAnimating])
            [self stopAnimation];
    });
    [view addSubview:self.indicator];
}

- (void)stopAnimation {
    if ([self.indicator isAnimating]) {
        [self.indicator stopAnimating];
        [self.indicator removeFromSuperview];  
    }
}
@end
请注意,我添加了一条规则,如果指示器没有在12秒内被触发停止,那么类将自行停止指示器

现在,我要做的就是在代码中我想启动指示器的每个地方添加这一行:

 [[ProgressView shared] startAnimation:self.view];
要添加此行以停止它,请执行以下操作:

 [[ProgressView shared] stopAnimation];

您可以为您的活动指示器定制一个类,并具有显示/隐藏方法,用于在当前显示视图控制器上显示/隐藏指示器。您可以使用“MBProgressHUD”框架。不仅如此,还有一些第三方框架。你是指应用程序委托中的UIWindow吗?如果现在,我怎样才能到达它?这不会带来坏的事情吗™ 如果屏幕上有一个弹出警报当前可见,因为弹出窗口将是
键窗口