Как добавить кнопку отмены между двумя другими кнопками (сложенными) в UIAlertView (iOS)

Я пытаюсь создать 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];

но безрезультатно. Возможно ли вообще то, что я пытаюсь сделать?


person SAHM    schedule 03.04.2012    source источник


Ответы (3)


У меня есть два дополнительных момента к этому ответу.

1) Хотя, насколько мне известно, Apple не отклонила приложение для разумной модификации UIAlertView; Они сказали, что иерархию представлений таких классов, как UIAlertView, следует считать частной.

2) Этот вопрос является хорошим примером того, почему вы должны задавать вопрос больше о своей конечной цели, а не о шагах, которые нужно выполнить. Единственная причина, по которой я знаю, о чем этот вопрос, - это комментарий, оставленный на мой ответ здесь.

Ответ:

Благодаря вашему комментарию я знаю, что вы хотите создать UIAlertView, в котором кнопки располагаются друг над другом, даже если кнопок всего две.

Я считаю, что наиболее логичным местом для такого кода является категория. Поскольку обычно код, необходимый для управления представлением предупреждения, должен быть связан с вызовом 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];

Этот код приводит к предупреждению, подобному этому:

введите описание изображения здесь

person NJones    schedule 03.04.2012
comment
Как то же самое можно было реализовать в Swift? - person iOS; 02.09.2015

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

Может помочь,

Ваше здоровье.

person Nilesh    schedule 03.04.2012
comment
Это будет работать до порядка кнопок, но это не настоящая кнопка отмены. Он будет иметь тот же цвет фона, что и две другие кнопки. - person SAHM; 03.04.2012
comment
Эй, если вы хотите, чтобы кнопка была такой же, как кнопка отмены по умолчанию, создайте свои собственные настраиваемые кнопки с разными изображениями и установите цель на свой viewController. Поскольку UIAlertView является подвидом UIView, вы можете добавить кнопку в качестве подвидов. - person Nilesh; 03.04.2012
comment
Спасибо за комментарий; но я не пытаюсь воссоздать этот класс; Я просто хотел посмотреть, есть ли способ получить индекс фактической кнопки отмены между двумя другими индексами. - person SAHM; 03.04.2012

Установите для кнопки отмены значение nil и просто добавьте ее вместо других кнопок.

person Eager Logic    schedule 03.04.2012
comment
Это будет работать до порядка кнопок, но это не настоящая кнопка отмены. Он будет иметь тот же цвет фона, что и две другие кнопки. - person SAHM; 03.04.2012