我一直在尝试解决这个问题,但我似乎找不到最好的方法。我很困惑,因为对于如何完成这个看似简单的任务似乎有不同的答案/意见。
我希望能够拥有一个名为 ActivityIndicatorController 的可重用类。该控制器有两个主要方法:activateIndicator 和 deactivateIndicator。它需要一个 UIView 作为参数/属性以及一个 NSString 作为标签。激活后,它将关闭 UIView 中的用户交互并添加一个矩形子视图(带有 alpha 和圆角)、一个 UIActivityIndicator 控件和一个用于状态文本的 UILabel。这是可取的,因为这样我不必在每个视图控制器中都有自定义 UIActivityIndicatorView 代码,也不必在每个 NIB 中设置 ActivityIndicator。
我从根本上遇到的问题是如何启动添加和动画 ActivityIndicator 的过程。我尝试过的一些方法根本不显示新视图。其他人工作,但 ActivityIndicator 不动画。
我曾尝试在 activateIndicator 方法中使用 [NSThread detachNewThreadSelector:@selector(startAnimating) toTarget:activityIndicator withObject:nil],但这不会显示新的 UIView。
我曾尝试从调用方法中使用 [NSThread detachNewThreadSelector:@selector(activateIndicator) toTarget:activityIndicatorController withObject:nil],但这会将新 UIView 的整个创建放在一个单独的线程中。
现在的问题:
第 1 部分:我知道所有 UI 都应该在主线程上处理,对吗?
第 2 部分:使用 [NSThread detachThreadSelector] 与 NSOperation 有什么区别/优点/缺点?
第 3 部分:是否更好:
(a) 将冗长的操作发送到一个新的后台线程,并回调主线程或
(b) 将 UIActivityIndicatorView startAnimating 方法发送到单独的线程,并在主线程上运行冗长的进程
为什么?
这是我当前的代码:
ActivityViewController 类:
-(void)activateIndicator {
NSLog(@"activateIndicator called");
if (isActivated || !delegateView)
return;
NSLog(@"activateIndicator started");
[delegateView.view setUserInteractionEnabled:NO];
[delegateView.navigationController.view setUserInteractionEnabled:NO];
[delegateView.tabBarController.view setUserInteractionEnabled:NO];
float w = [[UIScreen mainScreen] bounds].size.width;
float h = [[UIScreen mainScreen] bounds].size.height;
NSLog(@"Width = %f\nHeight = %f", w, h);
if (!disabledView) {
disabledView = [[[UIView alloc] initWithFrame:CGRectMake((w - kNormalWidth) / 2.0, (h - kNormalHeight) / 2.0, kNormalWidth, kNormalHeight)] autorelease];
disabledView.center = [[[delegateView.view superview] superview] center];
[disabledView setBackgroundColor:[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.85]];
CALayer *layer = [disabledView layer];
NSLog(@"layer=%@",layer);
NSLog(@"delegate=%@",[layer delegate]);
layer.cornerRadius = 12.0f;
}
if (!activityIndicator) {
activityIndicator = [[[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(kNormalWidth / 2, 10.0f, 40.0f, 40.0f)] autorelease];
[activityIndicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleWhiteLarge];
activityIndicator.center = disabledView.center;
}
if (!activityLabel) {
activityLabel = [[[UILabel alloc] initWithFrame:CGRectMake(10.0f, 100.0f, kNormalWidth - 20, 38)] autorelease];
activityLabel.text = labelText;
activityLabel.textAlignment = UITextAlignmentCenter;
activityLabel.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.0f];
activityLabel.textColor = [UIColor colorWithWhite:1.0f alpha:1.0f];
activityLabel.center = disabledView.center;
}
[[[delegateView.view superview] superview] addSubview:disabledView];
[[[delegateView.view superview] superview] addSubview:activityIndicator];
[[[delegateView.view superview] superview] addSubview:activityLabel];
[NSThread detachNewThreadSelector:@selector(startAnimating) toTarget:activityIndicator withObject:nil];
}
从应用程序中的多个位置调用代码:
ActivityIndicatorController *aic = [[ActivityIndicatorController alloc] init];
aic.delegateView = self;
aic.labelText = @"Test...";
[aic activateIndicator];
//DO LENGTHY WORK ON MAIN THREAD
[aic deactivateIndicator];
[aic release], aic = nil;