Отключение выделения в фоновом режиме при наличии индикатора активности

Я добавляю индикатор активности поверх представления и хочу отключить выбор в фоновом режиме, когда индикатор активности включен. Также по какой-то причине мой индикатор активности все еще вращается примерно 30-45 секунд (в зависимости от скорости сети) после того, как данные отображаются в виде таблицы. Я создал категорию для индикатора активности.

Код категории индикатора активности:

- (UIView *)overlayView {
    return objc_getAssociatedObject(self, OverlayViewKey);
}

- (void)setOverlayView:(UIView *)overlayView {
    objc_setAssociatedObject(self, OverlayViewKey, overlayView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (void)showActivityIndicatorForView:(UIView *)view {
    self.overlayView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
    self.center = self.overlayView.center;
    [view setUserInteractionEnabled:NO];
    [[UIApplication sharedApplication] beginIgnoringInteractionEvents];
    [self.overlayView setUserInteractionEnabled:NO];
    [self startAnimating];
    [self.overlayView addSubview:self];
    [view addSubview:self.overlayView];
    [view bringSubviewToFront:self.overlayView];
    self.hidesWhenStopped = YES;
    self.hidden = NO;

}

- (void)hideActivityIndicatorForView:(UIView *)view {
    [self stopAnimating];
    [self.overlayView setUserInteractionEnabled:YES];
    [self.overlayView removeFromSuperview];
    [[UIApplication sharedApplication] endIgnoringInteractionEvents];
    [view setUserInteractionEnabled:YES];
}

Использование в контроллере табличного представления:

@interface MyTableViewController()
@property (nonatomic, strong) UIActivityIndicatorView *activityIndicator;
@end

@implementation MyTableViewController
- (id) initWithSomething:(NSString *)something {
    self = [super init];

    if (self) {
        self.activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
        self.activityIndicator.overlayView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    [self getDataServiceRequest];
    [self.activityIndicator showActivityIndicatorForView:self.navigationController.view];
}

- (void)requestCompletionCallBack sender:(ServiceAPI *)sender {
// Do something here with the data
    [self.activityIndicator hideActivityIndicatorForView:self.navigationController.view];

    dispatch_async(dispatch_get_main_queue(), ^{
        [self.tableView reloadData];
    });
}
@end

Что я здесь делаю не так? Почему я все еще могу выбирать данные в фоновом режиме при включенном индикаторе активности и даже после отключения взаимодействия с пользователем.


person tech_human    schedule 28.11.2016    source источник


Ответы (2)


Переместите ваш вызов hideActivityIndicatorForView внутрь вызова dispatch_async(dispatch_get_main_queue(). Это вызов пользовательского интерфейса, который должен выполняться в основном потоке.

Что касается того, как отключить другие действия на вашем контроллере представления, у вас есть несколько вариантов. Одна простая вещь, которую я сделал, - это поместил индикатор активности в представление, прикрепленное ко всему экрану, с параметром opaque = false и черным цветом с настройкой альфа 0,5. Таким образом, содержимое внизу будет видно, но пользователь не сможет щелкнуть по нему. Вам нужно добавить выход в свой «завитушийВид» и показать-скрыть его вместо того, чтобы показывать / скрывать представление индикатора активности.

person Duncan C    schedule 28.11.2016
comment
Мне помог перемещение вызова hideActivityIndicatorForView внутри dispatch_async. Теперь индикатор моей активности исчезает, и вскоре после этого я вижу данные на экране. При этом я не вижу сценария, когда индикатор активности все еще вращается, пока данные отображаются на экране. Думаю, мне стоит пропустить добавление непрозрачного покрытия. Спасибо, @Duncan C! - person tech_human; 28.11.2016

dispatch_async(dispatch_get_main_queue(), ^{ [self.tableView reloadData]; }); исправить [self performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];

person Allen.Yang    schedule 28.11.2016