我有一个带有各种视图控制器的简单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次。
使用通过这些参数设置并根据需要设置为开和关的某种静态指示器的最佳方法是什么?
答案 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的共享实例调用上述方法。从情节提要中启用UIActivityIndicatorView的动画属性。
显示:
AppDelegate.shared.showLoading(isShow: true)
隐藏:
AppDelegate.shared.showLoading(isShow: false)
截屏:
答案 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)
谢谢大家的帮助, 我决定制作一个具有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] == 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];