Использование одного и того же UIActivityIndicatorView во многих контроллерах представления - PullRequest
0 голосов
/ 04 февраля 2019

У меня есть простое приложение для 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 раз.

Как лучше всего использовать какой-то статический индикатор, который будет установлен с этими параметрами и будетвключается и выключается по требованию?

Ответы [ 5 ]

0 голосов
/ 05 февраля 2019

Спасибо всем за помощь, я решил создать одноэлементный класс с переменной 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];
0 голосов
/ 04 февраля 2019

Я бы посоветовал вам создать суперкласс для ваших контроллеров представления и добавить туда функциональность счетчика, и пусть ваши контроллеры представления наследуют его.

Контроллер представления суперкласса будет выглядеть примерно так:

// .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

Теперь, чтобы унаследовать его, сделайте следующее в вашем файле контроллеров представления:

#import "SuperclassViewController.h"

@interface YourViewController : SuperclassViewController;

/** properties and methods */

@end

Затем вы можете вызвать [self showIndicator] и [self hideIndicator] в ваших представлениях контроллеров, когда это необходимо, без какого-либо дополнительного кодирования.

0 голосов
/ 04 февраля 2019

Вы можете создать отдельный контроллер вида для отображения индикатора загрузки во всех контроллерах вида.Вам нужно написать код один раз, поместить следующий код в файл 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)

Снимок экрана:

Screenshot of progress vc

0 голосов
/ 04 февраля 2019

Вот тот, который я использую в 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
0 голосов
/ 04 февраля 2019

Вы можете создать индикатор активности в UIWindow, а затем показать / скрыть его от любого UIViewController.

. Чтобы получить окно, используйте: UIApplication.shared.keyWindow

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...