Я долго пытался поиграть с этим, и я не могу найти лучший подход. Я запутался, потому что, кажется, есть разные ответы / мнения о том, как выполнить эту, казалось бы, простую задачу.
Я хочу иметь многократно используемый класс ActivityIndicatorController. Этот контроллер имеет два основных метода: activIndicator и deactivateIndicator. Он принимает UIView в качестве аргумента / свойства, а также NSString для метки. После активации он отключит взаимодействие с пользователем в UIView и добавит подпредставление прямоугольника (с альфа-каналом и закругленными углами), элемент управления UIActivityIndicator и UILabel для текста состояния. Это желательно, потому что таким образом мне не нужно иметь пользовательский код UIActivityIndicatorView в каждом контроллере представления или настраивать ActivityIndicator в каждом NIB.
Основная проблема, с которой я столкнулся, заключается в том, как запустить этот процесс добавления и анимации ActivityIndicator. Некоторые методы, которые я пробовал, вообще не отображают новый вид. Другие работают, но ActivityIndicator не анимирует.
Я пытался использовать [NSThread detachNewThreadSelector: @selector (startAnimating) toTarget: activityIndicator withObject: nil] внутри метода activIndicator, но это не отображает новый UIView.
Я пытался использовать [NSThread detachNewThreadSelector: @selector (activIndicator) toTarget: activityIndicatorController withObject: nil] из вызывающего метода, но это поместило бы все создание нового UIView в отдельный поток.
Теперь к вопросу:
Часть 1: Я понимаю, что все интерфейсы должны обрабатываться в главном потоке, это правильно?
Часть 2: В чем разница / преимущество / недостаток использования [NSThread detachThreadSelector] по сравнению с NSOperation?
Часть 3: лучше ли:
(a) отправить длительную операцию в новый фоновый поток с обратным вызовом в основной поток ИЛИ
(b) отправить метод startAnimating UIActivityIndicatorView в отдельный поток и запустить длительный процесс в главном потоке
И почему?
Вот мой текущий код:
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;