我想要按顺序显示几个UIAlertViews,只有在前一个UIAlertView被解除后才会显示下一个UIAlertView(用户单击okay)。
我知道didDismissWithButtonIndex委托并添加了一个标签,但这并没有太大帮助,因为最多可以调用3个UIAlertViews,并且不一定每次都以相同的顺序。见代码:
if(condition 1){
alert1 = // UIAlertView[[.....
[alert1 show]
}
if(condition 2){
alert2 = // UIAlertView[[.....
[alert2 show]
}
if(condition 3){
alert3 = // UIAlertView[[.....
[alert3 show]
}
上面只会添加3个警报(取决于满足的条件数量),这不是我想要的。我希望能够在用户点击确定按钮后一次只显示一个,然后显示下一个(如果有)。
我想到可能会将消息添加到队列中,然后处理该队列,每次取消警报时都会删除警报,但我不确定id是如何进行的。
任何想法都会非常感激。 感谢
答案 0 :(得分:0)
您可以在UIAlertView委托方法中轻松完成此操作,一旦取消警报视图,就会调用此方法。因此,UIAlertViewDelegate定义了以下委托方法:
– alertView:didDismissWithButtonIndex:
实现该方法,并确保您的类是您创建的UIAlertViews的委托。此方法是根据用户解散的下一个警告显示的理想场所。
如果您的要求是“按顺序显示最多三个警报,但并不总是以相同的顺序显示”我可能会将警报放入数组中,然后在委托方法中获取数组中的下一个警报显示。它不一定比那更复杂;关键是委托方法实现是显示下一个警报的最佳位置。
伪代码示例:
定义一个数组; NSMutableArray *警告_;
- (void)showAlertSequence {
if ( !alerts_ ) {
alerts_ = [[NSMutableArray alloc] init];
}
[alerts_ addObjects;<My alerts>];
[self showSequencedAlertFrom:nil];
}
- (BOOL)showSequencedAlertFrom:(UIAlertView *)sourceAlertView {
if ( !sourceAlertView ) {
[[alerts_ objectAtIndex:0] show];
}
else {
NSInteger index = [alerts_ indexOfObject:sourceAlertView];
if ( index < [alerts_ count] ) {
[[alerts_ objectAtIndex:index++] show];
}
}
return NO;
}
– alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)index {
// Show the next alert or clean up if we're at the end of the sequence.
if ( ![self showSequencedAlertFrom:alertView] ) {
[alerts_ removeAllObjects];
}
}
撇开;三个连续警报将真正惹恼用户;)
答案 1 :(得分:0)
我做过的一件事就是使用基于块的UIAlertViews,在AlertView上添加一个类别。
这是.h文件
@interface UIAlertView (WithBlocks)
- (id) initWithTitle:(NSString *)title message:(NSString *)message;
- (void) addButtonWithTitle:(NSString *)title andBlock:(void(^)())block;
@end
这是.m文件
static NSString *BUTTON_BLOCK_KEY = @"alertview-button-blocks";
@interface UIAlertView()
- (void) runBlock: (void (^)())block;
@end
@implementation UIAlertView (WithBlocks)
/**
* Initialized an alert view with a title and message.
*/
- (id) initWithTitle:(NSString *)title message:(NSString *)message
{
self = [self initWithTitle:title message:message delegate:nil cancelButtonTitle:nil otherButtonTitles:nil];
if (self) {
self.delegate = self;
NSMutableArray *buttonBlocks = [NSMutableArray array];
objc_setAssociatedObject(self, BUTTON_BLOCK_KEY, buttonBlocks, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return self;
}
/**
* Adds a button with a title and a block to be executed when that button is tapped.
*/
- (void) addButtonWithTitle:(NSString *)title andBlock:(void (^)())block
{
// Add the button
[self addButtonWithTitle:title];
NSMutableArray *buttonBlocks = objc_getAssociatedObject(self, BUTTON_BLOCK_KEY);
if (!block) {
block = ^{ /* empty block */ };
}
[buttonBlocks addObject:[[[block copy] retain] autorelease]];
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
NSMutableArray *buttonBlocks = objc_getAssociatedObject(self, BUTTON_BLOCK_KEY);
void (^block)() = (void (^)()) [buttonBlocks objectAtIndex:buttonIndex];
// Due to a timing issue, the current window is still the UIAlertView for a very
// short amount of time after it has been dismissed which messes up anything
// trying to get the current window in the blocks being run.
// Ergo, the block is being delayed by a tiny bit. (Amount determined through limited testing)
[self performSelector:@selector(runBlock:) withObject:block afterDelay:0.25];
}
- (void) runBlock: (void (^)())block
{
block();
}
@end
然后,您可以通过以下代码将警报视图链接在一起
void(^continueBlock)(void) = ^{
// Display more alertviews here
};
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Title" message:@"message"];
[alert addButtonWithTitle:@"Continue" andBlock:continueBlock];
[alert addButtonWithTitle:@"Dismiss" andBlock:^{
// Display more alertviews here
}
[alert show];
[alert release];
答案 2 :(得分:0)
我也在寻找这个问题的解决方案。这是我最终为自己的应用程序解决它的方式:
static BOOL alertShowing = FALSE;
UIAlertView *alert0 = [[UIAlertView alloc] initWithTitle:@"AlertView 0" message:@"This is the first alert" delegate:self cancelButtonTitle:nil otherButtonTitles:@"Yes",@"No", nil];
[alert0 setTag:0];
alertShowing = TRUE;
[alert0 show];
while (alertShowing) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.2]];
}
UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:@"AlertView 1" message:@"This is the second alert" delegate:self cancelButtonTitle:nil otherButtonTitles:@"Yes",@"No", nil];
[alert1 setTag:1];
alertShowing = TRUE;
[alert1 show];
while (alertShowing) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.2]];
}
// add some more alerts here for dramatic effect ...
您的按钮处理程序必须在每个退出路径中设置alertShowing = FALSE'
。
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
// Deal with handling responses for your different alerts here.
switch ([alertView tag]) {
case 0:
// handler first alert here
break;
case 1:
// handler second alert here
break;
default:
// etc.
break;
}
alertShowing = FALSE;
}
可能有更好的方法来坐和旋转,而不是创建一个新的运行循环,并且有一些重复的代码可能更好地通用化。从好的方面来说,它很简单,不需要一堆排队逻辑。我正在为这个模式使用#define来防止手动输入它,并且它在我的情况下运行良好。
答案 3 :(得分:0)
以下是我使用像你建议的那样使用警报队列的方法。
@property (strong, nonatomic) NSMutableArray *alertQueue;
@property (nonatomic) BOOL showingAlert;
- (void)showAlert:(UIAlertView *)alert {
if (self.showingAlert) {
[self.alertQueue addObject:alert];
}
else {
self.showingAlert = YES;
[alert show];
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if ([self.alertQueue count]) {
UIAlertView *alert = [self.alertQueue objectAtIndex:0];
[self.alertQueue removeObjectAtIndex:0];
[alert show];
}
else self.showingAlert = NO;
}
然后,只要您想显示警报,只需创建UIAlertView并将其传递给showAlert方法,它只会在所有早期警报被解除后显示。