如何在 UIAlertView(iOS)中的其他两个按钮(堆叠)之间添加取消按钮

Posted

技术标签:

【中文标题】如何在 UIAlertView(iOS)中的其他两个按钮(堆叠)之间添加取消按钮【英文标题】:How to add Cancel button between two other buttons (stacked) in UIAlertView (iOS) 【发布时间】:2012-04-03 15:54:47 【问题描述】:

我正在尝试创建一个带有三个按钮(将被堆叠)的 UIAlertView。我希望取消按钮位于其他两个按钮之间的中间。我尝试将 cancelButtonIndex 设置为 1,但如果还有其他两个按钮,它只会将它们放在索引 0 和 1 处。我知道我可以更改按钮的名称,但我想要取消按钮的深蓝色格式.

编辑:** 请注意 - 我知道如何以正确的顺序获取标题的三个按钮,但前提是所有三个按钮本质上看起来都像“其他”按钮;我希望取消按钮具有取消按钮深蓝色背景,以便它看起来像一个常规的取消按钮。 **

我试过了

UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:title message:msg delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:button1Title,button2Title,nil] autorelease];
alert.cancelButtonIndex = 1;
[alert show];

UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:title message:msg delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:nil] autorelease];
alert.cancelButtonIndex = 1;
[alert addButtonWithTitle:button1Title];
[alert addButtonWithTitle:button2Title];
[alert show];

UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:title message:msg delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:addButtonWithTitle:button1Title,nil] autorelease];
alert.cancelButtonIndex = 1;
[alert addButtonWithTitle:button2Title];
[alert show];

无济于事。是否有可能完成我想做的事情?

【问题讨论】:

【参考方案1】:
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:title message:msg delegate:self        cancelButtonTitle:nil otherButtonTitles:nil] autorelease];
[alert addButtonWithTitle:button1Title];
[alert addButtonWithTitle:@"Cancel"];
[alert addButtonWithTitle:button2Title];
[alert show];

可能会有所帮助,

干杯。

【讨论】:

这将在按钮顺序上起作用,但它不是真正的取消按钮。它将具有与其他两个按钮相同的背景颜色。 嘿,如果您希望按钮与默认取消按钮相同,请使用不同的图像创建自己的自定义按钮并将目标设置为您的 viewController。由于 UIAlertView 是 UIView 的子视图,因此您可以将按钮添加为子视图。 感谢您的评论;但我不想重新创建这个类;我只是想看看是否有办法在其他两个索引之间获取实际取消按钮的索引。【参考方案2】:

我对这个答案有两个辅助点。

1) 虽然,据我所知,Apple 并没有因为合理修改UIAlertView 而拒绝应用程序;他们说像UIAlertView 这样的类的视图层次结构应该被认为是私有的。

2) 这个问题是一个很好的例子,说明了为什么您应该提出更多关于您的最终目标而不是实现目标的步骤的问题。我知道这个问题是关于什么的唯一原因是我的回答 here 留下的评论。

答案:

由于您的评论,我知道您希望创建一个具有堆叠按钮的 UIAlertView,即使只有 2 个按钮。

我发现像这样的代码最合乎逻辑的地方是在一个类别中。由于通常操作警报视图所需的代码需要围绕show 调用,我创建了一个我调用的类别方法而不是show,而该方法又调用show 本身。

-(void)showWithButtonsStacked
    static NSString *tempButtonTitle = @"SomeUnlikelyToBeUsedTitle";
    BOOL willAddFakeButton = (self.numberOfButtons == 2); // Button are only side by side when there's 2
    if (willAddFakeButton)
        self.clipsToBounds = YES;
        [self addButtonWithTitle:tempButtonTitle]; // add temp button so the alertview will stack
    
    BOOL hasCancelButton = (self.cancelButtonIndex != -1); // If there is a cancel button we don't want to cut it off
    [self show];
    if (willAddFakeButton)
        UIButton *cancelButton = nil;
        UIButton *tempButton = nil;
        for (UIButton *button in self.subviews) 
            if ([button isKindOfClass:[UIButton class]])
                if (hasCancelButton && [button.titleLabel.text isEqualToString:[self buttonTitleAtIndex:self.cancelButtonIndex]])
                    cancelButton = button;
                 else if ([button.titleLabel.text isEqualToString:tempButtonTitle]) 
                    tempButton = button;
                
            
        
        if (hasCancelButton) // move in cancel button
            cancelButton.frame = tempButton.frame;
        
        [tempButton removeFromSuperview];

        // Find lowest button still visable.
        CGRect lowestButtonFrame = CGRectZero;
        for (UIButton *button in self.subviews) 
            if ([button isKindOfClass:[UIButton class]])
                if (button.frame.origin.y > lowestButtonFrame.origin.y)
                    lowestButtonFrame = button.frame;
                
            
        

        // determine new height of the alert view based on the lowest button frame
        CGFloat newHeight = CGRectGetMaxY(lowestButtonFrame) + (lowestButtonFrame.origin.x * 1.5);
        self.bounds = CGRectMake(0, 0, self.bounds.size.width, newHeight);        
    

此方法实现其目标的方式是向警报视图添加一个临时按钮以强制警报视图堆叠按钮,然后删除临时按钮并调整高度。由于它是一个类别方法,您只需调用它即可使用它:

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Test title" message:@"message" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil];
[alert showWithButtonsStacked];

此代码会产生如下警告:

【讨论】:

如何在 swift 中实现相同的功能?【参考方案3】:
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:title message:msg delegate:self cancelButtonTitle:nil otherButtonTitles:nil] autorelease];
[alert addButtonWithTitle:button1Title];
[alert addButtonWithTitle:@"Cancel"];
[alert addButtonWithTitle:button2Title];
[alert setCancelButtonIndex:1]; // to make it look like cancel button
[alert show];

【讨论】:

【参考方案4】:

将取消按钮设置为nil,然后将其添加到其他按钮中

【讨论】:

这将在按钮顺序上起作用,但它不是真正的取消按钮。它将具有与其他两个按钮相同的背景颜色。

以上是关于如何在 UIAlertView(iOS)中的其他两个按钮(堆叠)之间添加取消按钮的主要内容,如果未能解决你的问题,请参考以下文章

更改 UIAlertView 中的按钮标题颜色

从 iOS 8 中的 UIAlertView 中删除 alpha

UIAlertView 按钮(子视图)未在 iOS 7 中显示

如何在 iOS 8 中使用 UIAlertView? [复制]

带有单选按钮 iOS 的 UIAlertView [关闭]

如何从 UIAlertView 迁移(在 iOS8 中已弃用)