iPad的UIActionSheet显示多次

10

我有一个名为-showMoreTools:的方法,其代码如下:

- (IBAction) showMoreTools:(id)sender {
    UIActionSheet *popupQuery = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:nil destructiveButtonTitle:@"Close" otherButtonTitles:@"Add Bookmark", @"Add to Home Screen", @"Print", @"Share", nil];
    popupQuery.actionSheetStyle = UIActionSheetStyleDefault;
    popupQuery.dismiss
    [popupQuery showFromBarButtonItem:moreTools animated:YES];
    [popupQuery release];
}
当用户点击一个UIBarButtonItem时,它会显示那个UIActionSheet,但是如果用户想关闭UIActionSheet而不是点击关闭按钮(即点击UIBarButtonItem),那么它会在第一个UIActionSheet上再次显示UIActionSheet

有没有办法通过再次点击UIBarButtonItem来关闭UIActionSheet

非常感谢 - 我是iOS编程的新手!

5个回答

33
为了在点击两次按钮时取消显示,您需要跟踪当前正在显示的ActionSheet。我们在iPad应用程序中执行此操作,效果很好。
在具有showMoreTools的类中,在标题中添加:
@interface YourClassHere : NSObject <UIActionSheetDelegate> {
      UIActionSheet* actionSheet_;  // add this line
}

在类文件中,将其更改为:
-(IBAction) showMoreTools:(id)sender {
    // currently displaying actionsheet?
    if (actionSheet_) {
        [actionSheet_ dismissWithClickedButtonIndex:-1 animated:YES];
        actionSheet_ = nil;
        return;
    }

    actionSheet_ = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:nil destructiveButtonTitle:@"Close" otherButtonTitles:@"Add Bookmark", @"Add to Home Screen", @"Print", @"Share", nil];
    actionSheet_.actionSheetStyle = UIActionSheetStyleDefault;
    [popupQuery showFromBarButtonItem:moreTools animated:YES];
    [actionSheet_ release];  // yes, release it. we don't retain it and don't need to
}


- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {
    // just set to nil
    actionSheet_ = nil;
}

当我遇到同样的问题时,这个解决方案对我非常有效,谢谢。我想知道为什么苹果不提及这一点,因为他们在“将拥有按钮的工具栏添加到弹出窗口的穿透视图列表”时明确地使其发生。 - Bryan
此外,我认为您应该在actionSheet clickedButtonAtIndex:中将actionSheet_设置为nil。 - Bryan
你不需要这样做。如果你选择了一个按钮,clickedButtonAtIndex方法会被调用,然后didDismissWithButtonIndex方法也会被调用。在那个方法中放置=nil只是必要的。我刚刚在调试器中仔细检查过了。 - christophercotton
刚好碰到了一个情况,Bryan是正确的。当我从UIActionSheet:clickedButtonAtIndex弹出一个UIAlertView时,didDismissWithButtonIndex没有被调用。 - Filipe Pina
条件 if (actionSheet_) 可以替换为 if ([actionSheet_ superview])。我使用了 DTFoundation 中的 DTActionSheet,因此覆盖 cancel 方法不适合我。 - Roman B.

1
我找到了另一种解决方法。问题在于使用showFromBarButtonItem时,工具栏视图会自动添加到弹出窗口的穿透视图列表中。当直接使用UIPopoverController时,您可以修改(并清除)穿透视图,但是作为UIActionSheet的一部分呈现时,则无法进行修改。
无论如何,通过使用showFromRect,就不会有工具栏被自动添加到其穿透视图中的弹出窗口。因此,如果您知道按钮栏所在的(大致)矩形区域,可以使用以下代码:
CGRect buttonRect = CGRectIntersection(toolbar.frame, CGRectMake(0, 0, 60, self.frame.size.height));
[popupQuery showFromRect:buttonRect inView:self animated:YES];

在上面的例子中,我的按钮位于工具栏的左侧。

1
这种方法的一个问题是,如果您支持旋转,则需要在旋转后管理弹出窗口的位置。 - Steven Fisher

0

使用

- (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated

0

尝试通过设置标志(是/否)

-(void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated

你的意思是如果 actionsheet 是可见的,就将其设置为“是”。在点击另一个按钮时,检查 actionsheet 是否可见是不正确的... - user687522

0

我的方法类似于christophercotton的方法。

在我的showActionSheet方法中,我检查操作表是否可见而不是已实例化:

- (IBAction)showActionSheet:(id)sender
{
    if ([self.fullActionSheet isVisible]) {
        [self.fullActionSheet dismissWithClickedButtonIndex:-1 animated:NO];
        _fullActionSheet = nil;
        return;
    }

    //actionsheet code
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接