可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have discovered a strange problem when using UIActionSheet on the iPhone (iOS 4.2). Consider this code:
- (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);
}
If you start this application, the actionsheet behaves as expected. That means the cancelButtonIndex is always 0, and the button indexes are reported correctly. 1 for button "one" and so on. If you comment in the line for adding the seventh button, the actionsheet produces a sort of tableview, with the cancel button on an extra line. If I press the "one" button in this case, the buttonindex variable is 0, but so is the cancelButtonIndex. It is impossible to tell if the user has tapped the "cancel" or the "one" button. That doesn't seem like it should be this way. Does anyone disagree? Thanks for your help.
回答1:
I ran into the same issue even though I already was including the Cancel Button as the last one in the action sheet and setting its index accordingly. My problems had to do with the 'Destructive' button. After some investigation, here is my take on the problem:
After N buttons have been added to the actionsheet, it switches its layout to put the Destructive button at the top and the Cancel button at the bottom. In between is a scrollable view that includes all of the other buttons. Other sources indicate that this is a a table view.
N is 7 for Portrait orientation and 5 for Landscape orientation. N is 9 for Portrait orientation on larger, 4" screen. These numbers are for all buttons including Cancel and Destructive. To be clear, N is the largest number of buttons before the switch. N+1 buttons causes the UIActionSheet to switch to the scrollable view.
It does not matter where in the action sheet you had originally put the Cancel and Destructive buttons within the action sheet. Once the limit has been reached, the Destructive button is moved to the top and the Cancel is moved to the bottom.
The problem is that the indices are not adjusted accordingly. So, if you did not initially add the Cancel as the last button and the Destructive as the first, the wrong index will be reported in actionSheet:clickedButtonAtIndex: as the initial report stated.
So, if you are going to have more than N buttons in your action sheet you MUST add the Destructive button to the actionSheet as the first button to the action sheet. You MUST add the Cancel button as the last button added to the action sheet. When initially constructing the sheet just leave both as nil, as described in another answer.
回答2:
I've just had this problem. Solve it by not setting the cancel button initially. I set the buttons individually something like this:
for(int index = 0; index < buttonTotal; index++)
{
[actionSheet addButtonWithTitle:[NSString stringWithFormat:buttonText, [buttonItems objectAtIndex: index]]];
}
[actionSheet addButtonWithTitle:@"Cancel"];
actionSheet.cancelButtonIndex = actionSheet.numberOfButtons;
I believe the zero index is used by the destructiveButton if you use it so the other buttons will increment from there, otherwise they will start from 0.
Not sure I agree with the table option since above a certain amount, the buttons default to a scrollable list.
回答3:
file a bug about the problem. Include a little sample project and wait for some months to hear back from them.
For now you can set up your buttons statically in the init
UIActionSheet *actionSheet = [[UIActionSheet alloc]
initWithTitle:@"TestSheet"
delegate:self
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:nil
otherButtonTitles: @"one", @"two", @"three", @"four", @"five", @"six", @"seven", nil];
works without problems.
回答4:
1) Instantiate the actionview using
[[UIActionSheet alloc]
InitWithTitle:delegate:cancelButtonTitle:destructiveButtonTitle:OtherButtonTitles:]
without either the cancel button or destructive button (set them to nil)
2) Add all of the buttons as normal, using [myActionSheet addButtonWithTitle:(NSString *)]
.
3) If you want a special button, add it using the same method as step 2, and set the title to whatever (@"Cancel"
, for instance);
4) Now set the property [myActionSheet setCancelButtonIndex:]
to the index of the last button on the actionsheet, which was the cancel button made. Do the same for a destructive button. (These are -1 by default, which causes them not to be shown)
Note that a destructive button will always appear on top, and a cancel button will always appear on bottom, that cannot be changed.
Also, you can certainly add the cancel/destructive button at index 0, and add all of the other buttons after that. However now the first index of your other buttons is 1, instead of zero. This can be confusing if you have an array that corresponds with the alertview buttons.
回答5:
Do like as below:
UIActionSheet *actionSheet = [[UIActionSheet alloc]
initWithTitle:@"TestSheet"
delegate:self
cancelButtonTitle:@"Cancel"
destructiveButtonTitle:@"Delete"
otherButtonTitles: @"one", @"two", @"three", @"four", @"five", @"six", @"seven", @"eight", nil];
It means that define the destructive button as destructiveButtonTitle
. AVOID using destructive/cancel button in the otherButtonTitles
.