开发者

UIActionSheet in Landscape has incorrect buttonIndicies

开发者 https://www.devze.com 2023-02-28 10:25 出处:网络
I have an action sheet that is causing me grief on the iphone in Landscape orientation. Everything displays just fine, but in Landscape, the first real button has the same index as the cancel button a

I have an action sheet that is causing me grief on the iphone in Landscape orientation. Everything displays just fine, but in Landscape, the first real button has the same index as the cancel button and so the logic doesn't work.

I've tried creating the actionSheet using initWithTitle: delegate: cancelButtonTitle: destructiveButtonTitle: otherButtonTitles: but that was just the same, my current code is as follows;

UIActionSheet* actionMenu = [[UIActionSheet alloc] init];

actionMenu.delegate = self;
actionMenu.title = folderentry.Name;
actionMenu.cancelButtonIndex = 0;

[actionMenu addButtonWithTitle:NSLocalizedString(@"str.menu.cancel",nil)];

[self addActiveButtons:actionMenu forEntry:folderentry];
[actionMenu showInView:[self.navigationController view]];
[actionMenu release];

The addActiveButtons method basically configures which buttons to add which it does using code like this;

[menu addButtonWithTitle:NSLocalizedString(@"str.menu.sendbyemail",nil)];

There are perhaps 6 buttons at times so in landscape mode the actionSheet gets displayed like this;

UIActionSheet in Landscape has incorrect buttonIndicies

My delegate responds like this;

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {

NSLog(@"Cancel Button Index is : %d",actionSheet.cancelButtonIndex);
NSLog(@"Button clicked was for index : %d",buttonIndex);

NSString *command = [actionSheet buttonTitleAtIndex:buttonIndex];

DLog(@"COMMAND IS: %@ for index: %d",command,buttonIndex);

if ([command isEqualToString:NSLocalizedString(@"str.menu开发者_JAVA百科.sendbyemail",nil)]) {

    // Do stuff here

}

if ( ... similar blocks ... ) { }

}

In the example shown, I am finding that cancelButtonIndex is 0 as expected, but so is the button index for the first other button! This means if I click on the second (Save to Photos) button for example, my debug output looks like this;

Cancel Button Index is : 0

Button clicked was for index : 1

COMMAND IS: Send by Email for index: 1

I've tried various permutations and am now tearing my hair out wondering what I'm missing. I've had a good search around but the other problems people seem to be having are display issues, rather than functionality ones.

Can anyone see where I've gone wrong?

PS. I know this isn't the greatest UI experience, but I figure that most users will actually be in portrait most of the time or using the iPad version of the app so I'm prepared to accept the actionsheet default behaviour for landscape assuming I can get it to actually work!


OK, fixed it by counting how many buttons I was adding and then adding the cancel button as the last option, so my code looks like this;

int added = [self addActiveButtons:actionMenu forEntry:folderentry];

[actionMenu addButtonWithTitle:NSLocalizedString(@"str.menu.cancel",nil)];
actionMenu.cancelButtonIndex = added;

Hope that helps someone else struggling witht the same issue!


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 it's layout to put the Destructive button at the top and the Cancel button at the button. In between is a scrollable view that includes all of the other buttons. Other sources indicate that this is a a table view.

For the iPhone, N is 7 for Portrait orientation and 5 for Landscape orientation. Those numbers are for all buttons including Cancel and Destructive.

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.


I had the same problem. To fix it, I just create an actionSheet with nil for all the buttons, and added buttons manually afterwards. Lastly, in the handler, ignore the firstOtherButtonIndex because it will be wrong (even if you set it ahead of time). Instead, assume that it is 1 because index 0 is the cancel button in this example. Here's the code:

NSArray *items = [NSArray arrayWithObjects:@"one", @"two", @"three", nil];
UIActionSheet* actionSheet = [[[UIActionSheet alloc] initWithTitle:@"Title" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil] autorelease];
[actionSheet addButtonWithTitle:@"Cancel"];
for (NSString *title in items) {
    [actionSheet addButtonWithTitle:title];
}
[actionSheet addButtonWithTitle:@"Destroy"];

// set these if you like, but don't bother setting firstOtherButtonIndex.
actionSheet.cancelButtonIndex = 0;
actionSheet.destructiveButtonIndex = [items count]+1;

Also, don't forget to show this from a tab view if you're on an iPhone because the tab bar steals touch events and prevents the lower button from being hit.


My solution is to initialize like this specifying only the destructiveButtonTitle...

    UIActionSheet * as =[[[UIActionSheet alloc] initWithTitle:nil
                                                 delegate:self 
                                        cancelButtonTitle:nil 
                                   destructiveButtonTitle:@"Cancel" 
                                        otherButtonTitles:nil] autorelease];
[as addButtonWithTitle:@"Button 1"];
[as addButtonWithTitle:@"Button 2"];

That way you get the Cancel button at index 0 always and your own buttons begin at index 1 even when there is a scroll view.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号