当 activity 指标存在时禁用后台选择
Disabling selection in the background when activity indicator is present
我正在视图顶部添加 activity 指示器,并希望在 activity 指示器打开时禁用背景中的 select 离子。同样出于某种原因,在 table 视图上显示数据后,我的 activity 指示器仍然旋转了大约 30-45 秒(取决于网络速度)。我为 activity 指标创建了一个类别。
Activity指标类别代码:
- (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];
}
table 视图控制器中的用法:
@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
我在这里做错了什么?为什么在 activity 指示器打开时甚至在禁用用户交互后我仍然能够在后台 select 数据。
将对 hideActivityIndicatorForView 的调用移到对 dispatch_async(dispatch_get_main_queue()
的调用中。这是一个 UI 调用,需要在主线程上完成。
至于如何禁用视图控制器上的其他操作,您有几种选择。我做过的一件简单的事情是将 activity 指示器放在固定到整个屏幕的视图中,设置为 opaque=false,颜色为黑色,alpha 设置为 0.5。这样下面的内容是可见的,但用户不能点击它。您需要向您的 "coveringView" 添加一个插座并显示隐藏它而不是 showing/hiding activity 指示器视图。
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
修理它
[self performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
我正在视图顶部添加 activity 指示器,并希望在 activity 指示器打开时禁用背景中的 select 离子。同样出于某种原因,在 table 视图上显示数据后,我的 activity 指示器仍然旋转了大约 30-45 秒(取决于网络速度)。我为 activity 指标创建了一个类别。
Activity指标类别代码:
- (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];
}
table 视图控制器中的用法:
@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
我在这里做错了什么?为什么在 activity 指示器打开时甚至在禁用用户交互后我仍然能够在后台 select 数据。
将对 hideActivityIndicatorForView 的调用移到对 dispatch_async(dispatch_get_main_queue()
的调用中。这是一个 UI 调用,需要在主线程上完成。
至于如何禁用视图控制器上的其他操作,您有几种选择。我做过的一件简单的事情是将 activity 指示器放在固定到整个屏幕的视图中,设置为 opaque=false,颜色为黑色,alpha 设置为 0.5。这样下面的内容是可见的,但用户不能点击它。您需要向您的 "coveringView" 添加一个插座并显示隐藏它而不是 showing/hiding activity 指示器视图。
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
修理它
[self performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];