【问题标题】:UIActionSheet buttonIndex values faulty when using more than 6 custom buttons?使用超过 6 个自定义按钮时 UIActionSheet buttonIndex 值错误?
【发布时间】:2011-03-10 16:11:46
【问题描述】:

我在 iPhone (iOS 4.2) 上使用 UIActionSheet 时发现了一个奇怪的问题。考虑这段代码:

- (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);
}

如果您启动此应用程序,操作表将按预期运行。这意味着 cancelButtonIndex 始终为 0,并且正确报告了按钮索引。 1 代表按钮“一”,依此类推。如果您在添加第七个按钮的行中添加注释,则操作表会生成一种表格视图,而取消按钮位于额外的一行上。如果我在这种情况下按下“一”按钮,则 buttonindex 变量为 0,但 cancelButtonIndex 也是如此。无法判断用户是否点击了“取消”或“一”按钮。这似乎不应该是这样的。有人不同意吗?感谢您的帮助。

【问题讨论】:

  • 操作表上有六个按钮?真的吗?我建议使用表格作为选项...
  • 如果您不应该使用它,那么拥有一个可以在滚动视图中处理 6 个以上按钮的操作表有什么意义?
  • 遇到了同样的问题,显然是bug
  • 令人惊讶的是,这个错误——而且它显然是一个错误——在 iOS 7.0+ 中仍然存在。

标签: iphone ios uiactionsheet


【解决方案1】:

我遇到了同样的问题,即使我已经将取消按钮作为操作表中的最后一个按钮并相应地设置了它的索引。我的问题与“破坏性”按钮有关。经过一番调查,这是我对这个问题的看法:

  • 在将 N 个按钮添加到操作表后,它会切换布局,将破坏性按钮放在顶部,将取消按钮放在底部。中间是一个包含所有其他按钮的可滚动视图。其他来源表明这是一个表格视图。

  • N 为 7(纵向)和 5(横向)。 N 是 9 表示在更大的 4" 屏幕上的纵向方向。这些数字适用于所有按钮,包括取消和破坏性。需要明确的是,N 是切换前的最大按钮数。N+1 按钮导致 UIActionSheet 切换到可滚动的视图。

  • 您最初将“取消”和“破坏性”按钮放在操作表中的哪个位置并不重要。达到限制后,Destructive 按钮将移至顶部,而 Cancel 按钮将移至底部。

  • 问题是没有相应地调整索引。因此,如果您最初没有将 Cancel 作为最后一个按钮,将 Destructive 作为第一个按钮,则会在 actionSheet:clickedButtonAtIndex: 中报告错误的索引,如初始报告所述。

  • 因此,如果您要在操作表中包含 N 个以上的按钮,则必须将破坏性按钮添加到操作表,作为操作表的 first 按钮。您必须将取消按钮添加为添加到操作表的 last 按钮。最初构建工作表时,只需将两者都保留为 nil,如另一个答案中所述。

【讨论】:

  • 这是真正正确的答案——不是上面标记的答案。感谢 Rich 发帖。对于读者,请注意关于按钮排序的第四个项目符号。
  • 这是多么可笑的行为。我经常想知道为什么苹果会做出某些决定。这是其中之一。感谢您的提示。
【解决方案2】:

我刚遇到这个问题。通过最初不设置取消按钮来解决它。我单独设置按钮是这样的:

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

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

如果你使用它,我相信 破坏性按钮会使用零索引,因此其他按钮将从那里递增,否则它们将从 0 开始。

不确定我是否同意表格选项,因为超过一定数量,按钮默认为可滚动列表。

【讨论】:

  • 你应该做actionSheet.cancelButtonIndex = [actionSheet addButtonWithTitle:@"Cancel"];
  • 本地化不会破坏这个解决方案吗?
  • 我认为本地化会破坏这个解决方案(由于不同语言环境中的“取消”字符串不同)。刚刚实现 @user102008 的解决方案,它没有问题(它必须根据索引确定取消按钮,而不是字符串)
【解决方案3】:

file a bug 关于这个问题。包括一个小示例项目,然后等待几个月才能收到他们的回复。

现在您可以在 init 中静态设置按钮

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

工作没有问题。

【讨论】:

  • 感谢您的提示,不过我需要从数组中设置按钮,上面只是一个示例,指出 addButtonWithTitle 方法似乎不起作用。
【解决方案4】:

1) 使用实例化动作视图

[[UIActionSheet 分配] InitWithTitle:delegate:cancelButtonTitle:破坏性ButtonTitle:OtherButtonTitles:]

没有取消按钮或破坏性按钮(将它们设置为 nil)

2) 使用 [myActionSheet addButtonWithTitle:(NSString *)] 照常添加所有按钮。

3) 如果你想要一个特殊的按钮,使用与步骤 2 相同的方法添加它,并将标题设置为任何内容(例如@"Cancel");

4) 现在将属性[myActionSheet setCancelButtonIndex:] 设置为actionsheet 上最后一个按钮的索引,即取消按钮。对破坏性按钮执行相同操作。 (默认为-1,不显示)

  • 请注意,破坏性按钮将始终显示在顶部,而取消按钮将始终显示在底部,无法更改。

  • 此外,您当然可以在索引 0 处添加取消/破坏性按钮,然后添加所有其他按钮。但是现在其他按钮的第一个索引是 1,而不是零。如果您有一个与 alertview 按钮对应的数组,这可能会造成混淆。

【讨论】:

    【解决方案5】:

    如下所示:

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

    表示将破坏性按钮定义为destructiveButtonTitle。避免在otherButtonTitles 中使用破坏性/取消按钮。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-22
      • 1970-01-01
      • 2021-09-17
      相关资源
      最近更新 更多