在许多视图控制器中使用相同的UIActivityIndi​​catorView

时间:2019-02-04 13:16:09

标签: ios objective-c xcode

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

我想使用一个UIActivityIndi​​catorView,它将在用户单击按钮时启动,并在委托方法上停止。 显然,我希望指标在每个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次。

使用通过这些参数设置并根据需要设置为开和关的某种静态指示器的最佳方法是什么?

5 个答案:

答案 0 :(得分:1)

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

注意::我不在Objective-C中使用Swift中的代码。因此,您需要在目标C中转换代码。

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

ProgressVC.swift:

class func viewController() -> ProgressVC {
   return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ProgressVC") as! ProgressVC
}

在AppDelegate中添加以下代码。

AppDelegate.swift:

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的共享实例调用上述方法。从情节提要中启用UIActivityIndi​​catorView的动画属性。

显示:

AppDelegate.shared.showLoading(isShow: true)

隐藏:

AppDelegate.shared.showLoading(isShow: false)

截屏:

Screenshot of progress vc

答案 1 :(得分:0)

您可以在UIWindow中创建活动指示器,然后可以在任何UIViewController中显示/隐藏它。

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

答案 2 :(得分:0)

这是我在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

答案 3 :(得分:0)

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

超类视图控制器看起来像这样:

// .h-file
@interface SuperclassViewController : UIViewController

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

@end

// .m file
#import "SuperclassViewController.h"

@interface SuperclassViewController ()
@property (nonatomic, strong) UIActivityIndicatorView *indicator;    
@end

@implementation SuperclassViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    _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.layer.cornerRadius = 6;
    self.indicator.center = self.view.center;

    [self.indicator startAnimating];
}

- (void)showIndicator {
    [self.view addSubview:self.indicator];
}

- (void)hideIndicator {
    [self.indicator removeFromSuperview];
}
@end

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

#import "SuperclassViewController.h"

@interface YourViewController : SuperclassViewController;

/** properties and methods */

@end

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

答案 4 :(得分:0)

谢谢大家的帮助, 我决定制作一个具有UIActivityIndi​​catorView变量的单例类。

这是该类的声明:

#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] == YES)
        [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];