Значения UIActionSheet buttonIndex неисправны при использовании более 6 пользовательских кнопок?


Я обнаружил странную проблему при использовании UIActionSheet на iPhone (iOS 4.2). Рассмотрим этот код:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    [self.window addSubview:viewController.view];
    [self.window makeKeyAndVisible];

    UIActionSheet *actionSheet = [[UIActionSheet alloc] 
                                  initWithTitle:@"TestSheet" 
                                  delegate:self 
                                  cancelButtonTitle:@"Cancel" 
                                  destructiveButtonTitle:nil 
                                  otherButtonTitles: nil];

    [actionSheet addButtonWithTitle:@"one"];
    [actionSheet addButtonWithTitle:@"two"];
    [actionSheet addButtonWithTitle:@"three"];
    [actionSheet addButtonWithTitle:@"four"];
    [actionSheet addButtonWithTitle:@"five"];
    [actionSheet addButtonWithTitle:@"six"];
    //uncomment next line to see the problem in action
    //[actionSheet addButtonWithTitle:@"seven"];

    [actionSheet showInView:window];
    [actionSheet release];

    return YES;
}
- (void) actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    NSLog(@"buttonIndex: %d, cancelButtonIndex: %d, firstOtherButtonIndex: %d",
          buttonIndex, 
          actionSheet.cancelButtonIndex, 
          actionSheet.firstOtherButtonIndex);
}

Если вы запустите это приложение, actionsheet будет вести себя так, как ожидалось. Это означает, что cancelButtonIndex всегда равен 0, и индексы кнопок отображаются правильно. 1 для кнопки "один" и так далее. Если вы прокомментируете в строке добавление седьмой кнопки, actionsheet создает своего рода tableview, с кнопкой отмены на дополнительной строке. Если я нажму кнопку "один" в этом случае переменная buttonindex равна 0, но также и переменная cancelButtonIndex. Невозможно сказать, нажал ли пользователь кнопку" Отмена "или кнопку" один". Не похоже, что все должно быть именно так. Кто-нибудь не согласен? Спасибо за вашу помощь.

5 25

5 ответов:

Я столкнулся с той же проблемой, несмотря на то, что я уже включал кнопку отмены в качестве последней в таблице действий и устанавливал ее индекс соответственно. Мои проблемы были связаны с "разрушительной" кнопкой. После некоторого исследования, вот мой взгляд на проблему:

  • После добавления N кнопок в actionsheet он переключает его расположение, чтобы поместить деструктивную кнопку вверху и кнопку отмены внизу. Между ними находится прокручиваемый вид, который включает в себя все другая кнопка. Другие источники указывают, что это табличное представление.

  • N - это 7 для портретной ориентации и 5 для альбомной ориентации. N - 9 для портретной ориентации на большом 4-дюймовом экране. Эти цифры для всех кнопок, включая отмену и разрушение. Чтобы было понятно, N-это наибольшее число кнопок перед переключателем. В N+1 кнопки вызывает UIActionSheet, чтобы переключиться в представление с возможностью прокрутки.

  • Это не имеет значения, где в списке действий вы имели первоначально поместите кнопки Отмена и разрушение в лист действий. Как только лимит достигнут, кнопка деструкции перемещается наверх, а кнопка отмены-вниз.

  • Проблема в том, что индексы не корректируются соответствующим образом. Таким образом, если вы изначально не добавили отмену в качестве последней кнопки и разрушение в качестве первой, то неверный индекс будет сообщен в actionSheet:clickedButtonAtIndex: как указано в первоначальном отчете.

  • Итак, если вы собираетесь иметь более N кнопок в вашем листе действий вы должны добавить деструктивную кнопку в листе действий как первую кнопку в листе действий. Вы должны добавить кнопку Отмена в качестве последней кнопки, добавленной в таблицу действий. При первоначальном построении листа просто оставьте оба значения равными нулю, как описано в другом ответе.

У меня только что была эта проблема. Решите эту проблему, не устанавливая кнопку отмены изначально. Я устанавливаю кнопки по отдельности примерно так:

   for(int index = 0; index < buttonTotal; index++)
   {
    [actionSheet addButtonWithTitle:[NSString stringWithFormat:buttonText, [buttonItems objectAtIndex: index]]];
   }

   [actionSheet addButtonWithTitle:@"Cancel"];
   actionSheet.cancelButtonIndex = actionSheet.numberOfButtons;

Я полагаю, что нулевой индекс используется destructiveButton, если вы используете его, чтобы другие кнопки увеличивались оттуда, иначе они будут начинаться с 0.

Не уверен, что я согласен с опцией таблицы, так как выше определенного количества, кнопки по умолчанию имеют прокручиваемый список.

Файл ошибки о проблеме. Включите небольшой примерный проект и подождите несколько месяцев, чтобы получить от них ответ.

Теперь вы можете настроить свои кнопки статически в init

UIActionSheet *actionSheet = [[UIActionSheet alloc] 
                              initWithTitle:@"TestSheet" 
                              delegate:self 
                              cancelButtonTitle:@"Cancel" 
                              destructiveButtonTitle:nil 
                              otherButtonTitles: @"one", @"two", @"three", @"four", @"five", @"six", @"seven", nil];

Работает без проблем.

1) Создайте экземпляр actionview с помощью

[[UIActionSheet alloc] InitWithTitle: делегат: cancelButtonTitle:destructiveButtonTitle: OtherButtonTitles:]

Без кнопки отмены или деструктивной кнопки (установите их равными нулю)

2) Добавьте все кнопки как обычно, используя [myActionSheet addButtonWithTitle:(NSString *)].

3) Если вам нужна специальная кнопка, добавьте ее, используя тот же метод, что и Шаг 2, и установите заголовок на что угодно (@"Cancel", например);

4) Теперь установите свойство [myActionSheet setCancelButtonIndex:] к индексу последней кнопки на листе действий, которая была сделана кнопкой отмены. Сделайте то же самое для деструктивной кнопки. (По умолчанию они равны -1, что приводит к тому, что они не отображаются)

  • Обратите внимание, что деструктивная кнопка всегда будет отображаться сверху, а кнопка отмены всегда будет отображаться снизу, что не может быть изменено.

  • Кроме того, вы можете, конечно, добавить кнопку отмены/разрушения в индексе 0, а затем добавить все остальные кнопки. Однако теперь первый индекс других ваших кнопок равен 1, а не нулю. Это может привести к путанице, если у вас есть массив, соответствующий кнопкам alertview.

Сделайте как показано ниже:

UIActionSheet *actionSheet = [[UIActionSheet alloc] 
                              initWithTitle:@"TestSheet" 
                              delegate:self 
                              cancelButtonTitle:@"Cancel" 
                              destructiveButtonTitle:@"Delete" 
                              otherButtonTitles: @"one", @"two", @"three", @"four", @"five", @"six", @"seven", @"eight", nil];

Это означает, что определите деструктивную кнопку как destructiveButtonTitle. Избегайте использования кнопки деструктив / отмена в otherButtonTitles.