Как поместить UIActivityIndicatorView в UIAlertController?
Мы уходим от MBProgressHUD, потому что он слишком глючный в нашем приложении и не имеет таких функций, как блокировка пользовательского ввода или предоставление кнопки отмены.
Итак, я попытался реализовать Swipesight'S Как отобразить индикатор активности в центре UIAlertController?, и я столкнулся с неправильным расположением индикатора:
он зеленый, потому что оттенок нашего приложения зеленый.
Как вы можете видеть, это не в Белом прямоугольник часть контроллера, но серый фон. Здесь используется нечто похожее на его решение "@62Shark":
// in implementation:
@property (nonatomic, strong) UIActivityIndicatorView *spinner;
@property (nonatomic, strong) UIAlertController *alertController;
// in init:
_alertController = [UIAlertController alertControllerWithTitle: @"Loading"
message: nil
preferredStyle: UIAlertControllerStyleAlert];
_spinner = [UIActivityIndicatorView new];
_spinner.translatesAutoresizingMaskIntoConstraints = false;
_spinner.userInteractionEnabled = false;
_spinner.color = [ThemingAssistant tintColor];
_spinner.frame = _alertController.view.bounds;
_spinner.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[_spinner startAnimating];
[_alertController.view addSubview: _spinner];
// ...
- (void) showOn: (UIViewController *)target
title: (NSString *)title
message: (NSString *)message
canCancel: (BOOL)canCancel
{
self.alertController.title = title;
self.alertController.message = message;
if (canCancel)
{
[self.alertController addAction:[UIAlertAction actionWithTitle: @"Cancel"
style: UIAlertActionStyleCancel
handler: ^(UIAlertAction *name){
[self customDismiss];
}]];
}
NSDictionary *views = @{@"pending" : self.alertController.view,
@"indicator" : self.spinner};
NSArray *constraints =
[NSLayoutConstraint constraintsWithVisualFormat: @"V:[indicator]-(-50)-|"
options: 0
metrics: nil
views: views];
[constraints arrayByAddingObjectsFromArray:
[NSLayoutConstraint constraintsWithVisualFormat: @"H:|[indicator]|"
options: 0
metrics: nil
views: views]];
[target presentViewController: self.alertController
animated: true
completion: nil];
}
Даже если это было в белом прямоугольнике, я боюсь, что он может столкнуться с текстом (кроме того, когда я получу его там, я хочу, чтобы он был в середине сверху, как это делает MBProgressHUD), поэтому мне нужно будет зарезервировать для него некоторое пространство.
Итак, мой вопрос двоякий: Как мне зарезервировать место дляUIActivityIndicatorView
в белом прямоугольнике UIAlertController
, а затем как я могу на самом деле поместить его туда?1 ответ:
Как JonasG Здесь есть свойство с именем
contentViewController
, и мы можем использовать KVC для доступаПример:
UIViewController *v = [[UIViewController alloc] init]; v.view.backgroundColor = [UIColor redColor]; [alertController setValue:v forKey:@"contentViewController"];
Итак, вот как должен выглядеть ваш код (протестирован и работает нормально):
- (IBAction)buttonClicked:(id)sender { self.alertController = [UIAlertController alertControllerWithTitle: @"Loading" message: nil preferredStyle: UIAlertControllerStyleAlert]; [self.alertController addAction:[UIAlertAction actionWithTitle: @"Cancel" style: UIAlertActionStyleCancel handler:nil]]; UIViewController *customVC = [[UIViewController alloc] init]; UIActivityIndicatorView* spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; [spinner startAnimating]; [customVC.view addSubview:spinner]; [customVC.view addConstraint:[NSLayoutConstraint constraintWithItem: spinner attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:customVC.view attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f]]; [customVC.view addConstraint:[NSLayoutConstraint constraintWithItem: spinner attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:customVC.view attribute:NSLayoutAttributeCenterY multiplier:1.0f constant:0.0f]]; [self.alertController setValue:customVC forKey:@"contentViewController"]; [self presentViewController: self.alertController animated: true completion: nil]; }
Вы можете переопределить
-preferredContentSize
, чтобы вернуть пользовательский размер в контроллер вида, который вы задаете какcontentViewController
.В нашем случае это
customVC
Результат:
Хотите, чтобы текст был быть ниже этого показателя ?
Я создал
UIViewController
сxib
, чтобы действовать в качестве пользовательского контроллера для нашегоcontentViewController
в первом примере мы создали контроллер вида без файла xib, теперь мы можем добавлять представления с помощью interface builder, я добавил индикатор активности и установил ограничения по центру по горизонтали и вертикали, а метка под индикатором активности, которая центрирована по горизонтали, вот мой interface builder:У нас меньше код:
- (IBAction)buttonClicked:(id)sender { self.alertController = [UIAlertController alertControllerWithTitle: nil message: nil preferredStyle: UIAlertControllerStyleAlert]; MyCustomViewController *v = [[MyCustomViewController alloc] init]; [self.alertController setValue:v forKey:@"contentViewController"]; [self presentViewController: self.alertController animated: true completion: nil]; }
Результат: