如何将 UIActivityIndicatorView 放入 UIAlertController 中?
How do I put a UIActivityIndicatorView in a UIAlertController?
我们将不再使用 MBProgressHUD,因为它在我们的应用程序中故障太多,并且没有阻止用户输入或提供取消按钮等功能。
因此,我尝试实施 Swipesight's How to display activity indicator in center of 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 一样),所以我需要一种方法来为它预留一些 space。
所以,我的问题有两个:如何在 UIAlertController
的白色矩形 中为 UIActivityIndicatorView
保留 space ],然后 我如何实际将它放在那里?
像这里提到的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];
}
You can override -preferredContentSize
to return a custom size in the
view controller that you are setting as contentViewController
.
在我们的例子中是 customVC
结果:
希望文本位于指标下方?
我创建了一个 UIViewController
和一个 xib
作为我们 contentViewController
的自定义控制器 在第一个例子中我们创建了没有 xib 文件的视图控制器,现在我们可以使用界面构建器添加视图,我添加了一个 Activity 指示器并将约束设置为水平和垂直居中,并且 activity 指示器下的标签水平居中,这是我的界面构建器:
我们现在的代码更少了:
- (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];
}
结果:
我们将不再使用 MBProgressHUD,因为它在我们的应用程序中故障太多,并且没有阻止用户输入或提供取消按钮等功能。
因此,我尝试实施 Swipesight's How to display activity indicator in center of 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 一样),所以我需要一种方法来为它预留一些 space。
所以,我的问题有两个:如何在 UIAlertController
的白色矩形 中为 UIActivityIndicatorView
保留 space ],然后 我如何实际将它放在那里?
像这里提到的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];
}
You can override
-preferredContentSize
to return a custom size in the view controller that you are setting ascontentViewController
.
在我们的例子中是 customVC
结果:
希望文本位于指标下方?
我创建了一个 UIViewController
和一个 xib
作为我们 contentViewController
的自定义控制器 在第一个例子中我们创建了没有 xib 文件的视图控制器,现在我们可以使用界面构建器添加视图,我添加了一个 Activity 指示器并将约束设置为水平和垂直居中,并且 activity 指示器下的标签水平居中,这是我的界面构建器:
我们现在的代码更少了:
- (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];
}
结果: