Как поместить UIActivityIndicatorView в UIAlertController?


Мы уходим от MBProgressHUD, потому что он слишком глючный в нашем приложении и не имеет таких функций, как блокировка пользовательского ввода или предоставление кнопки отмены.

Итак, я попытался реализовать Swipesight'S Как отобразить индикатор активности в центре UIAlertController?, и я столкнулся с неправильным расположением индикатора:

A < code>UIAlertController< / code > с "загрузкой" и цензурированным текстом в центре экрана, но индикатор активности далеко слева и ниже контроллера оповещения
он зеленый, потому что оттенок нашего приложения зеленый.

Как вы можете видеть, это не в Белом прямоугольник часть контроллера, но серый фон. Здесь используется нечто похожее на его решение "@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 3

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:

contentViewController

У нас меньше код:

- (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];

}

Результат:

Настраиваемое оповещение